1. Reactの概要
1.1 Reactとは
- React は、ユーザー インターフェイスを構築するための JavaScript ライブラリです。
- React の主な機能は、コンポーネント化、宣言型プログラミング、効率的な DOM 更新メカニズムです。
- React は Facebook によって開発およびオープンソース化され、最も人気のあるフロントエンド フレームワークの 1 つになりました。
1.2 Reactの特徴
- 宣言型プログラミング: React は宣言型プログラミング モデルを採用しており、コードが読みやすく理解しやすくなっています。
- コンポーネント化: React はページを複数のコンポーネントに分解し、各コンポーネントには独自の状態とライフサイクルがあるため、再利用とメンテナンスに便利です。
- 一方向データ フロー: React は一方向データ フロー モードを採用しており、親コンポーネントは props を通じて子コンポーネントにデータを渡し、子コンポーネントはコールバック関数を通じて親コンポーネントにデータを渡します。
- 仮想 DOM : React は仮想 DOM の技術を採用しており、前後の 2 つの仮想 DOM の違いを比較することで、ページの再描画やリフローを最小限に抑え、ページのパフォーマンスと応答速度を向上させます。
- 効率: React は効率的なアルゴリズムとメカニズムを使用して、ページをより高速にレンダリングし、より良いユーザー エクスペリエンスを提供します。
1.3 React の利点
- ユーザー エクスペリエンスの向上: React は仮想 DOM を使用するため、ページをより速く更新し、ユーザー エクスペリエンスを向上させることができます。
- コンポーネントベースの開発: React はコンポーネントベースの開発を採用しています。これにより、コードがよりモジュール化され再利用可能になり、開発効率が向上します。
- 高いコード保守性: React は一方向のデータフローを採用しているため、コードのデータフローが明確に可視化され、保守やデバッグに便利です。
- 活発なコミュニティ: React には巨大なコミュニティとエコシステムがあり、開発を容易にするための豊富なプラグインとコンポーネントを提供できます。
1.4 React の欠点 - React の欠点:
- 学習曲線は比較的急勾配であり、特定の JavaScript の基礎と JSX 構文の理解が必要です。
- 他の側面ではなく、ビュー レイヤーにのみ焦点を当て、他のライブラリやフレームワークと組み合わせて使用する必要があります。
- コードの複雑さは高く、多数のコンポーネントとロジック コードを記述する必要があります。
- IE8 以下のバージョンのブラウザはサポートされておらず、互換性のためにポリフィルが必要です。
2. Reactの基礎知識
2.1 JSX 構文
- JSX 構文の例:
const element = <h1>Hello, world!</h1>; // JSX语法
ReactDOM.render(element, document.getElementById('root')); // 渲染到页面
- JSX 式の例:
function formatName(user) {
return user.firstName + ' ' + user.lastName;
}
const user = {
firstName: 'Tony',
lastName: 'Stark'
};
const element = (
<h1>
Hello, {
formatName(user)}!
</h1>
);
ReactDOM.render(element, document.getElementById('root')); // 渲染到页面
- JSX 属性インスタンス:
const element = <div tabIndex="0">Hello, world!</div>; // JSX属性
ReactDOM.render(element, document.getElementById('root')); // 渲染到页面
2.2 コンポーネント
- 2.2 コンポーネント
-
例 1: Hello World コンポーネント
import React from 'react'; function HelloWorld() { return <h1>Hello, World!</h1>; } export default HelloWorld;
-
例 2: カウンターコンポーネント
import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>Count: { count}</p> <button onClick={ () => setCount(count + 1)}>Increment</button> <button onClick={ () => setCount(count - 1)}>Decrement</button> </div> ); } export default Counter;
-
例 3: テーブルコンポーネント
import React from 'react'; function Table(props) { const { data } = props; return ( <table> <thead> <tr> <th>Name</th> <th>Age</th> <th>Gender</th> </tr> </thead> <tbody> { data.map((item) => ( <tr key={ item.id}> <td>{ item.name}</td> <td>{ item.age}</td> <td>{ item.gender}</td> </tr> ))} </tbody> </table> ); } export default Table;
2.2.1 機能コンポーネント
- 機能部品
function Welcome(props) {
return <h1>Hello, {
props.name}</h1>;
}
ReactDOM.render(
<Welcome name="John" />,
document.getElementById('root')
);
2.2.2 クラスコンポーネント
- クラスコンポーネントは、React でコンポーネントを定義する方法であり、ES6 クラス構文を使用してコンポーネントを宣言します。
- クラス コンポーネントは React.Component クラスを継承し、コンポーネントの UI を記述するための render メソッドを実装する必要があります。
- クラス コンポーネントは、setState メソッドを通じて独自の状態を定義し、状態を更新し、コンポーネントを再レンダリングできます。
- クラス コンポーネントは、ユーザー インタラクションやその他のロジックを処理するための独自のメソッドを定義することもできます。
- クラス コンポーネントは、this.props を通じてアクセスされる入力データとして props を受け取ることができます。
- クラスコンポーネントのライフサイクルにはマウント、更新、アンマウントの 3 つのフェーズがあり、ライフサイクル メソッドを書き換えることで特定のロジックを実装できます。
例:
import React, {
Component } from 'react';
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
handleClick = () => {
this.setState({
count: this.state.count + 1 });
}
render() {
return (
<div>
<h1>{
this.props.title}</h1>
<p>Count: {
this.state.count}</p>
<button onClick={
this.handleClick}>Click me</button>
</div>
);
}
}
export default MyComponent;
フォームの例:
プロパティ/メソッド | 説明する |
---|---|
州 | コンポーネントの状態オブジェクト |
setState() | コンポーネントの状態を更新する |
小道具 | コンポーネント入力プロパティ |
与える() | コンポーネント UI の記述方法 |
コンポーネントDidMount() | コンポーネントのマウント後に呼び出されるメソッド |
コンポーネントDidUpdate() | コンポーネントの更新後に呼び出されるメソッド |
コンポーネントウィルアンマウント() | コンポーネントがアンマウントされる前に呼び出されるメソッド |
2.3 小道具と状態
- Props と State の違い:
相違点 | 小道具 | 州 |
---|---|---|
ストレージの場所 | 親コンポーネントから子コンポーネントに渡される | コンポーネントの内部初期化 |
可変ですか | 不変、読み取り専用 | 変数、変更可能 |
対応コンポーネントタイプ | 関数コンポーネントとクラスコンポーネント | クラスコンポーネントのみ |
ビューの更新をトリガーする | 親コンポーネントによって渡される props が変更されます | setState() メソッドはコンポーネント自体によって呼び出されます |
ライフサイクル | コンポーネントのライフサイクルには影響しません | shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate などのライフサイクルがトリガーされる場合があります。 |
- 小道具の使用:
function ParentComponent() {
const name = "小明";
return (
<ChildComponent name={
name} />
);
}
function ChildComponent(props) {
return (
<div>
<p>我是子组件</p>
<p>我的名字是:{
props.name}</p>
</div>
);
}
- 状態の使用:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
handleClick = () => {
this.setState({
count: this.state.count + 1
});
}
render() {
return (
<div>
<p>当前计数:{
this.state.count}</p>
<button onClick={
this.handleClick}>增加计数</button>
</div>
);
}
}
2.4 ライフサイクル
- React コンポーネントのライフサイクルには、マウント フェーズ、更新フェーズ、アンマウント フェーズが含まれます。
- マウント フェーズには、コンストラクター、getDerivedStateFromProps、render、componentDidMount が含まれます。
- 更新フェーズには、getDerivedStateFromProps、 shouldComponentUpdate、render、getSnapshotBeforeUpdate、componentDidUpdate が含まれます。
- アンマウントフェーズには、componentWillUnmount が含まれます。
2.5 イベント処理 - React のイベント処理はネイティブ DOM イベント処理とは異なり、合成イベント (SyntheticEvent) を使用してブラウザのネイティブ イベントをカプセル化し、ブラウザ間の一貫性を提供します。
- React では、アロー関数を使用するか、コンストラクターのバインド メソッドを使用して、イベント ハンドラーをコンポーネント インスタンスにバインドする必要があります。
- イベント ハンドラー関数の this のデフォルトは、イベントをトリガーした DOM 要素ではなく、コンポーネント インスタンスです。
- イベント ハンドラーのパラメーター e は、元のイベントと同じプロパティとメソッド (e.target、e.stopPropagation() など) を含む合成イベント オブジェクトです。
- React のイベント ハンドラーはイベントのバブリングを防ぐために false を返すことはできませんが、同じ効果を達成するには e.stopPropagation() または e.preventDefault() を使用する必要があります。
- サンプルコード:
class MyComponent extends React.Component {
handleClick = (e) => {
console.log('Button clicked!');
}
render() {
return (
<button onClick={
this.handleClick}>Click me</button>
);
}
}
テーブル構文の例:
イベント処理に反応する | 説明する |
---|---|
オンクリック | マウスクリックイベント |
ダブルクリック時 | マウスのダブルクリックイベント |
onMouseDown | マウスダウンイベント |
マウスアップ時 | マウスアップイベント |
onKeyDown | キーボードを押すイベント |
onKeyUp | キーボード発売イベント |
オンフォーカス | 要素がフォーカスイベントを取得する |
オンブラー | 要素がフォーカスを失ったイベント |
3. 高度な知識に反応する
3.1 高次成分
- 高次成分とは何ですか?
- 上位コンポーネントは、コンポーネントを引数として受け取り、新しいコンポーネントを返す関数です。
- 高次コンポーネントの役割は何ですか?
- 高次コンポーネントは、元のコンポーネントを変更することなく、コンポーネントの再利用、ロジックの抽象化、カプセル化を実現し、コンポーネントの機能を強化するのに役立ちます。
- 上位コンポーネントの実装方法は何ですか?
- プロパティ プロキシ: 元のコンポーネントをラップし、新しいプロパティをコンポーネントに渡すことで、コンポーネントの機能を強化します。
- 逆継承: 元のコンポーネントを継承し、そのメソッドを書き換えることによって、コンポーネントの機能を強化します。
- 高次コンポーネントの適用シナリオは何ですか?
- 条件付きレンダリング: 条件に基づいてさまざまなコンポーネントをレンダリングします。
- 認証と認可: ユーザーの認証ステータスと権限に基づいて、さまざまなコンポーネントをレンダリングします。
- データの取得と処理: データの取得と処理のロジックがコンポーネントから分離されているため、コンポーネントがより簡潔になり、再利用可能になります。
- 機能強化: ロギングやパフォーマンス統計の追加など、コンポーネントの機能を強化します。
- 高次成分の注意点は何ですか?
- 高次コンポーネントは、元のコンポーネントのプロパティと状態を変更してはなりません。
- 高レベルのコンポーネントは、元のコンポーネントのプロパティとコンテキストを透過的に送信する必要があります。
- 高次コンポーネントは関数型プログラミングの原則に従う必要があり、副作用があってはなりません。
3.2 フック
- 使用状態
import React, {
useState } from 'react';
function Example() {
// 声明一个叫 "count" 的 state 变量
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {
count} times</p>
<button onClick={
() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
- useEffect
import React, {
useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// 相当于 componentDidMount 和 componentDidUpdate:
useEffect(() => {
// 使用浏览器的 API 更新页面标题
document.title = `You clicked ${
count} times`;
});
return (
<div>
<p>You clicked {
count} times</p>
<button onClick={
() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
- useContext
import React, { useContext } from 'react'; const ThemeContext = React.createContext('light'); function App() { return ( <ThemeContext.Provider value="dark"> <Toolbar /> </ThemeContext.Provider> ); } function Toolbar(props) { return ( <div> <ThemedButton /> </div> ); } function ThemedButton() { const theme = useContext(ThemeContext); return <button>{ theme}</button>; }
- useReducer
import React, {
useReducer } from 'react';
const initialState = {
count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {
count: state.count + 1 };
case 'decrement':
return {
count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {
state.count}
<button onClick={
() => dispatch({
type: 'increment' })}>+</button>
<button onClick={
() => dispatch({
type: 'decrement' })}>-</button>
</>
);
}
- useコールバック
import React, { useState, useCallback } from 'react'; function Example() { const [count, setCount] = useState(0); const [text, setText] = useState(''); const handleChange = useCallback(e => { setText(e.target.value); }, []); return ( <div> <p>You clicked { count} times</p> <button onClick={ () => setCount(count + 1)}> Click me </button> <input value={ text} onChange={ handleChange} /> </div> ); }
- メモを使用する
import React, {
useState, useMemo } from 'react';
function Example() {
const [count, setCount] = useState(0);
const expensiveCount = useMemo(() => {
return count ** 2;
}, [count]);
return (
<div>
<p>You clicked {
count} times</p>
<p>Expensive count: {
expensiveCount}</p>
<button onClick={
() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
3.2.1 使用状態
- useState の基本的な使用法:
import React, {
useState } from 'react';
function Example() {
// 声明一个叫 "count" 的 state 变量
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {
count} times</p>
<button onClick={
() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
- useState は関数を使用して状態を更新します。
import React, {
useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(prevCount => prevCount + 1);
}
return (
<div>
<p>You clicked {
count} times</p>
<button onClick={
handleClick}>
Click me
</button>
</div>
);
}
-
useState は関数を初期値として受け入れることができます。
import React, { useState } from 'react'; function Example() { const [count, setCount] = useState(() => { const initialCount = 0; return initialCount; }); return ( <div> <p>You clicked { count} times</p> <button onClick={ () => setCount(count + 1)}> Click me </button> </div> ); }
-
useState は構造化代入を使用できます。
import React, { useState } from 'react'; function Example() { const [state, setState] = useState({ count: 0, name: '张三' }); function handleClick() { setState(prevState => { return { ...prevState, count: prevState.count + 1 }; }); } return ( <div> <p>{ state.name} clicked { state.count} times</p> <button onClick={ handleClick}> Click me </button> </div> ); }
3.2.2 使用効果
-
useEffect は React のフックで、データ取得や DOM 操作など、コンポーネント内の副作用操作を処理するために使用されます。
-
useEffect の基本的な使い方は次のとおりです。
import React, { useEffect } from 'react'; function Example() { useEffect(() => { // 在这里处理副作用操作 return () => { // 在组件卸载时执行清除操作 }; }, [/* 依赖项 */]); return <div>Example</div>; }
-
useEffect は 2 つのパラメータを受け取ります。最初のパラメータはコールバック関数で、副作用を処理するために使用されます。2 番目のパラメータは配列で、副作用操作の依存関係を指定するために使用されます。依存関係が変更された場合にのみ、副作用は再実行されます。実行された操作。
-
useEffect は、コンポーネントがアンマウントされたときにクリーンアップを実行するクリーンアップ関数を返すこともできます。
3.2.3 useContext
- コンポーネント間の通信には useContext を使用します
import React, {
useContext } from 'react';
// 创建一个context
const MyContext = React.createContext();
// 在父组件中设置context的值
function Parent() {
return (
<MyContext.Provider value="hello">
<Child />
</MyContext.Provider>
);
}
// 在子组件中使用context的值
function Child() {
const value = useContext(MyContext);
return <div>{
value}</div>;
}
3.3 リダックス
- Redux は、React でのデータ フローの管理を改善するのに役立つ状態管理ツールです。
- Redux には、ストア、アクション、リデューサーという 3 つの中心的な概念があります。
- ストアは Redux でデータが保存される場所であり、store.getState() を通じてストア内のデータを取得できます。
- Action は Redux のイベントを記述するオブジェクトであり、イベントのタイプを記述する type 属性が含まれている必要があります。
- レデューサーは Redux のイベントを処理する関数で、現在の状態とアクションを受け取り、新しい状態を返します。
- Redux を使用するには、redux と React-redux という 2 つのパッケージをインストールし、アプリケーション内にストアを作成する必要があります。
- Reduxを使用する場合、アクションとリデューサーを定義してストアに登録する必要があります。
- redux-devtools を使用すると、Redux アプリケーションを簡単にデバッグできます。
- Redux を React と組み合わせて使用すると、react-redux が提供する connect 関数を通じて Redux の状態を React コンポーネントのプロパティにマッピングすることもできます。
- Redux を使用する場合は、Redux を悪用しないように注意する必要があります。大量の共有状態を管理する必要がある場合にのみ使用してください。そうしないと、コードが複雑になり、保守が困難になります。
3.4 React ルーター - React ルーターとは何ですか?
- React Router は、React をベースにした強力なルーティング ライブラリで、アプリケーションにルーティング機能を追加して、ユーザーが URL を介してさまざまなページにアクセスできるようにします。
- Reactルーターの使い方
- React Router をインストールします。
npm install react-router-dom
- アプリケーションに React Router を導入します。
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
- コンポーネントを使用して
<Router>
アプリケーション全体をラップし、<Route>
コンポーネントを使用してルーティング ルールを定義し、<Link>
コンポーネントを使用してリンクを生成します。
- React Router をインストールします。
- React Routerの共通API
<Route>
コンポーネント: ルーティング ルールを定義し、path
とcomponent
2 つのプロパティを含みます。<Link>
コンポーネント: リンクを生成し、to
属性が含まれます。useHistory
フック: ページジャンプを実現するために使用できるルーティング履歴を取得します。
- React Router の高度な使用法
- ネストされたルーティング: ルーティング ルールを別のルーティング ルール内にネストします。
- 動的ルーティング: パラメータを使用してルーティング ルールを定義します
/users/:id
。 - ルーティング ガード: ルーティング ジャンプの前に、権限の検証またはその他の操作を実行します。
<Route>
これは、コンポーネントのrender
プロパティまたはカスタム コンポーネントを使用して実現できます。
4. 実際に反応する
4.1 React アプリケーションの作成
- create-react-app で React アプリケーションを作成する
- コンポーネントをアプリケーションに追加してレンダリングする
- props を使用してコンポーネントにデータを渡す
- 状態を使用してコンポーネントの内部状態を管理する
- コンポーネントイベントを処理する
- ライフサイクルメソッドを使用したコンポーネントの動作の制御
- React Router を使用してページ ルーティングを実装する
- Redux でアプリケーションの状態を管理する
- React Hooks を使用したコンポーネント コードの最適化
- React テスト ツールを使用した単体テスト
- React Native を使用したモバイル アプリの開発
- Next.js を使用したサーバー レンダリング
- React を使用して、GraphQL、TypeScript などの他のテクノロジー スタックと統合します。
- Reactを使って実際のプロジェクトを開発した経験の共有
- 概要と展望
フォーム構文:
シリアルナンバー | コンテンツ |
---|---|
1 | create-react-app で React アプリケーションを作成する |
2 | コンポーネントをアプリケーションに追加してレンダリングする |
3 | props を使用してコンポーネントにデータを渡す |
4 | 状態を使用してコンポーネントの内部状態を管理する |
5 | コンポーネントイベントを処理する |
6 | ライフサイクルメソッドを使用したコンポーネントの動作の制御 |
7 | React Router を使用してページ ルーティングを実装する |
8 | Redux でアプリケーションの状態を管理する |
9 | React Hooks を使用したコンポーネント コードの最適化 |
10 | React テスト ツールを使用した単体テスト |
11 | React Native を使用したモバイル アプリの開発 |
12 | Next.js を使用したサーバー レンダリング |
13 | React を使用して、GraphQL、TypeScript などの他のテクノロジー スタックと統合します。 |
14 | Reactを使って実際のプロジェクトを開発した経験の共有 |
15 | 概要と展望 |
4.2 React と他のフレームワークの統合
-
React と Vue.js の統合
サンプルコード:
// 在Vue.js组件中使用React组件 <template> <div> <my-react-component :prop1="value1" @event1="handleEvent"></my-react-component> </div> </template> <script> import MyReactComponent from './MyReactComponent'; export default { components: { 'my-react-component': MyReactComponent }, data() { return { value1: 'some value' } }, methods: { handleEvent() { // 处理React组件触发的事件 } } } </script>
-
React と Angular の統合
サンプルコード:
// 在Angular组件中使用React组件 import { Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { MyReactComponent } from './MyReactComponent'; @Component({ selector: 'app-my-angular-component', template: '<div #reactContainer></div>', }) export class MyAngularComponent implements OnInit { @ViewChild('reactContainer', { static: true }) reactContainer: ElementRef; @Input() prop1: string; ngOnInit() { ReactDOM.render(<MyReactComponent prop1={ this.prop1} />, this.reactContainer.nativeElement); } }
-
React と jQuery の統合
サンプルコード:
// 在jQuery插件中使用React组件 (function($) { $.fn.myJqueryPlugin = function(options) { const settings = $.extend({ }, options); return this.each(function() { const $this = $(this); const props = { prop1: settings.prop1 }; ReactDOM.render(<MyReactComponent { ...props} />, $this[0]); }); }; })(jQuery);
4.3 React パフォーマンスの最適化
4.4 React テスト - Jest と Enzyme を使用したコンポーネント テスト
- React Testing Library を使用したコンポーネントのテスト
- Cypress を使用したエンドツーエンドのテスト
- Sinon による単体テスト
- Mocha と Chai との統合テスト
- Jasmine を使用したフルスタック テスト
- シート:
テストフレームワーク | アドバンテージ | 欠点がある |
---|---|---|
は | 高速で使いやすく、スナップショット テストをサポート | 高度な統合、カスタマイズは容易ではない |
酵素 | 浅いレンダリングと深いレンダリングをサポートし、コンポーネントのライフサイクルを簡単にテストできます | React16の新機能には対応していません |
React テスト ライブラリ | ユーザーの行動とより一致しており、テストはより現実的です | コンポーネントの内部状態をテストするのは簡単ではありません |
ヒノキ | エンドツーエンドのテストを実行し、デバッグをサポートできます | 複数のブラウザをテストできない |
さもないと | 関数とオブジェクトをモックできるため、非同期コードのテストが簡単になります | 他のテスト フレームワークと連携する必要がある |
Mocha和Chai | 柔軟で使いやすく、他のテスト フレームワークと統合可能 | 手動でのインストールと構成が必要です |
ジャスミン | フルスタックテストが可能で、非同期コードのテストが容易 | 統合レベルは高くなく、カスタマイズは簡単ではありません |
5. 参考文献
5.1 React 公式ドキュメント
-
React 公式ドキュメント: https://reactjs.org/docs/getting-started.html
React官方文档是React框架的官方文档,提供了详细的React介绍、快速上手指南、组件API等内容,是学习React的必备资料。在这里,你可以了解到React的基本概念、核心特性、组件生命周期、事件处理等知识点,并且可以通过实例代码进行实践操作,加深对React的理解。同时,React官方文档也提供了React Native、React VR等相关技术的文档,方便开发者进行深入学习和应用。
5.2 React源码解析
- React源码解析官方文档:https://reactjs.org/docs/codebase-overview.html
- React源码解析系列博客:https://react.iamkasong.com/
- React源码解析视频教程:https://www.bilibili.com/video/BV1qE411b7cZ
- React源码解析Github仓库:https://github.com/facebook/react
- 表格:React源码解析书籍推荐
书名 | 作者 | 出版社 | 链接 |
---|---|---|---|
《React源码解析》 | 陈屹著 | 机械工业出版社 | https://book.douban.com/subject/30374649/ |
5.3 React实战教程- React官方文档:https://reactjs.org/docs/getting-started.html
- React中文文档:https://zh-hans.reactjs.org/
- 5.3 React实战教程:
- React小书:http://huziketang.mangojuice.top/books/react/
- React Native官方文档:https://reactnative.dev/docs/getting-started
- React Router官方文档:https://reactrouter.com/web/guides/quick-start
- Ant Design官方文档:https://ant.design/docs/react/introduce-cn
- Material-UI官方文档:https://material-ui.com/zh/getting-started/installation/
- Redux官方文档:https://redux.js.org/introduction/getting-started
- Mobx官方文档:https://mobx.js.org/README.html
- TypeScript官方文档:https://www.tslang.cn/docs/home.html
- Next.js官方文档:https://nextjs.org/docs/getting-started
- Gatsby官方文档:https://www.gatsbyjs.com/docs/