React 基础入门:搭建第一个 React 应用
环境搭建
在开始搭建 React 应用之前,我们首先要确保开发环境的搭建是正确且完整的。React 应用的开发依赖于 Node.js 环境,因为我们会使用 npm(Node Package Manager)来管理项目的依赖。
安装 Node.js
Node.js 可以从其官方网站(https://nodejs.org/)下载。根据你的操作系统,选择合适的安装包进行下载和安装。安装过程较为简单,按照安装向导的提示一步步操作即可。安装完成后,可以在命令行中输入以下命令来验证 Node.js 是否安装成功:
node -v
如果安装正确,该命令会输出版本号,例如 v14.17.0
。同时,npm 也会随着 Node.js 一同安装,同样可以在命令行中输入以下命令验证 npm 的安装:
npm -v
这会输出版本号,如 6.14.13
。
使用 create - react - app 创建项目
create - react - app
是一个官方推荐的用于快速搭建 React 应用的工具。它为我们提供了一个预配置好的开发环境,无需手动配置 Webpack、Babel 等工具,大大降低了 React 应用开发的入门门槛。
在全局安装 create - react - app
,可以使用以下命令:
npm install -g create - react - app
安装完成后,我们就可以使用 create - react - app
来创建一个新的 React 项目。在命令行中,进入你想要创建项目的目录,然后执行以下命令:
create - react - app my - first - react - app
这里的 my - first - react - app
是项目的名称,你可以根据自己的喜好进行命名。这个命令会在当前目录下创建一个名为 my - first - react - app
的文件夹,并在其中初始化一个 React 项目结构,同时安装所有必要的依赖。
创建完成后,进入项目目录:
cd my - first - react - app
然后启动开发服务器:
npm start
执行上述命令后,开发服务器会自动启动,并在默认浏览器中打开应用,通常是 http://localhost:3000
。如果一切顺利,你会看到一个默认的 React 欢迎页面,这表明你的 React 应用已经成功搭建并运行起来了。
React 项目结构剖析
在成功创建 React 项目后,让我们深入了解一下项目的目录结构。进入 my - first - react - app
目录,会看到以下主要文件和文件夹:
src 文件夹
src
文件夹是项目的核心源代码目录,所有的 React 组件、样式、逻辑等代码都应该放在这里。
- App.js:这是应用的主要组件文件。在 React 中,组件是构建用户界面的基本单元。
App.js
通常作为整个应用的顶层组件,其他组件会被引入并嵌套在App.js
中。以下是App.js
的默认代码示例:
import React from'react';
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App - header">
<img src={logo} className="App - logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App - link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
在这段代码中,我们定义了一个名为 App
的函数组件。函数组件是 React 中定义组件的一种简洁方式,它返回一个 JSX 元素。JSX 是一种 JavaScript 的语法扩展,看起来很像 HTML,它允许我们在 JavaScript 代码中编写类似 HTML 的结构来描述 UI。
- App.css:这个文件用于定义
App
组件的样式。React 项目通常采用模块化的 CSS 方式,每个组件有自己对应的 CSS 文件,这样可以避免样式冲突。例如,在App.css
中可以看到以下样式定义:
.App {
text - align: center;
}
.App - header {
background - color: #282c34;
min - height: 100vh;
display: flex;
flex - direction: column;
align - items: center;
justify - content: center;
font - size: calc(10px + 2vmin);
color: white;
}
.App - logo {
height: 40vmin;
pointer - events: none;
}
@media (prefers - reduced - motion: no - preference) {
.App - logo {
animation: App - logo - spin infinite 20s linear;
}
}
.App - link {
color: #61dafb;
}
@keyframes App - logo - spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
这些样式通过在 App.js
中引入 ./App.css
应用到 App
组件的各个部分。
- index.js:这是整个应用的入口文件。它负责将 React 组件渲染到 DOM 中。以下是
index.js
的默认代码:
import React from'react';
import ReactDOM from'react - dom';
import App from './App';
import './index.css';
ReactDOM.render(<App />, document.getElementById('root'));
在这段代码中,我们首先从 react - dom
中导入 ReactDOM
,它提供了将 React 元素渲染到 DOM 中的方法。然后,我们通过 ReactDOM.render
方法将 App
组件渲染到 HTML 页面中 id 为 root
的元素上。index.css
则是应用的全局样式文件。
public 文件夹
public
文件夹包含了应用的公共资源,如 HTML 文件、图片、favicon 等。
- index.html:这是应用的主 HTML 文件。它是整个应用在浏览器中呈现的基础结构。在
index.html
中,我们可以看到一个 id 为root
的<div>
元素,这就是ReactDOM.render
方法将 React 组件渲染到的位置。以下是index.html
的基本结构:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf - 8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device - width, initial - scale = 1" />
<meta name="theme - color" content="#000000" />
<meta name="description" content="Web site created using create - react - app" />
<link rel="apple - touch - icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
其中,%PUBLIC_URL%
是一个特殊的变量,在构建过程中会被替换为正确的路径。例如,%PUBLIC_URL%/favicon.ico
会在构建后指向实际的 favicon 文件路径。
node_modules 文件夹
node_modules
文件夹包含了项目所依赖的所有第三方模块。当我们使用 npm install
安装依赖时,这些依赖包就会被下载并安装到这个文件夹中。这个文件夹通常不需要手动修改,它由 npm 进行管理。
编写第一个自定义 React 组件
现在我们已经了解了 React 项目的基本结构,接下来开始编写我们的第一个自定义 React 组件。在 src
文件夹下创建一个新的文件夹,例如 components
,用于存放所有的自定义组件。然后在 components
文件夹中创建一个新的文件,命名为 HelloWorld.js
。
函数式组件
在 HelloWorld.js
中,我们首先通过函数式组件的方式来定义我们的 HelloWorld
组件。函数式组件是一个简单的 JavaScript 函数,它接受一个 props
对象作为参数,并返回一个 JSX 元素。以下是代码示例:
import React from'react';
function HelloWorld(props) {
return (
<div>
<h1>Hello, {props.name}!</h1>
</div>
);
}
export default HelloWorld;
在这个组件中,我们从 props
对象中获取 name
属性,并将其插入到 <h1>
标签中。props
是 React 中用于组件间传递数据的重要机制,父组件可以通过 props
向子组件传递数据。
类组件(Class - based Component)
除了函数式组件,React 还支持使用类来定义组件,这种方式被称为类组件。类组件提供了更多的功能,例如生命周期方法等。让我们用类组件的方式重新实现 HelloWorld
组件。在 components
文件夹下创建 HelloWorldClass.js
文件,代码如下:
import React, { Component } from'react';
class HelloWorldClass extends Component {
render() {
return (
<div>
<h1>Hello, {this.props.name}!</h1>
</div>
);
}
}
export default HelloWorldClass;
在类组件中,我们通过继承 React.Component
类来定义组件。render
方法是类组件必须实现的方法,它返回组件的 JSX 结构。与函数式组件一样,我们通过 this.props
获取父组件传递过来的数据。
在应用中使用自定义组件
定义好自定义组件后,我们需要在应用中使用它们。回到 App.js
文件,我们可以将刚刚创建的 HelloWorld
组件引入并使用。
引入函数式组件
在 App.js
中引入 HelloWorld
函数式组件,并传递一个 name
属性,代码如下:
import React from'react';
import logo from './logo.svg';
import './App.css';
import HelloWorld from './components/HelloWorld';
function App() {
return (
<div className="App">
<header className="App - header">
<HelloWorld name="React Learner" />
<img src={logo} className="App - logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App - link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
这样,在浏览器中打开应用,就会看到 Hello, React Learner!
的文本显示在页面上。
引入类组件
同样,我们也可以引入类组件 HelloWorldClass
。修改 App.js
如下:
import React from'react';
import logo from './logo.svg';
import './App.css';
import HelloWorldClass from './components/HelloWorldClass';
function App() {
return (
<div className="App">
<header className="App - header">
<HelloWorldClass name="React Class Learner" />
<img src={logo} className="App - logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App - link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
此时,浏览器中会显示 Hello, React Class Learner!
,说明类组件也成功引入并使用。
处理用户输入
在实际应用中,我们经常需要处理用户的输入。React 提供了一种方便的方式来处理表单输入,即通过受控组件和非受控组件。
受控组件
受控组件是指其值由 React 组件的 state 控制的表单元素。例如,一个文本输入框,我们可以通过 state 来管理其输入的值。在 components
文件夹下创建 InputComponent.js
文件,代码如下:
import React, { useState } from'react';
function InputComponent() {
const [inputValue, setInputValue] = useState('');
const handleChange = (event) => {
setInputValue(event.target.value);
};
return (
<div>
<input
type="text"
value={inputValue}
onChange={handleChange}
/>
<p>You entered: {inputValue}</p>
</div>
);
}
export default InputComponent;
在这段代码中,我们使用了 React 的 useState
Hook 来创建一个状态变量 inputValue
和一个更新这个状态的函数 setInputValue
。useState
是 React 16.8 引入的新特性,它允许我们在函数组件中使用 state。input
元素的 value
属性绑定到 inputValue
,并且 onChange
事件触发 handleChange
函数,在这个函数中我们通过 setInputValue
更新 inputValue
的值,从而实现实时显示用户输入的内容。
非受控组件
非受控组件是指表单元素的值不受 React state 控制,而是由 DOM 本身来管理。通常,我们会使用 ref
来访问非受控组件的值。以下是一个非受控组件的示例,同样在 components
文件夹下创建 UncontrolledInputComponent.js
文件:
import React, { useRef } from'react';
function UncontrolledInputComponent() {
const inputRef = useRef(null);
const handleSubmit = (event) => {
event.preventDefault();
alert('You entered:'+ inputRef.current.value);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={inputRef} />
<input type="submit" value="Submit" />
</form>
);
}
export default UncontrolledInputComponent;
在这个示例中,我们使用 useRef
Hook 创建了一个 inputRef
。ref
可以用来访问 DOM 元素,在 handleSubmit
函数中,我们通过 inputRef.current.value
获取输入框的值并弹出提示框。
组件间通信
在一个复杂的 React 应用中,组件之间需要进行通信以实现各种功能。React 提供了多种方式来进行组件间通信。
父子组件通信
父子组件通信是最常见的一种通信方式,通过 props
可以实现父组件向子组件传递数据。我们前面的 HelloWorld
组件示例就是一个父组件向子组件传递 name
属性的例子。子组件通过 props
接收父组件传递的数据并进行展示。
而子组件要向父组件传递数据,可以通过父组件传递一个回调函数给子组件,子组件在需要的时候调用这个回调函数,并将数据作为参数传递给父组件。例如,在 components
文件夹下创建 ChildComponent.js
和 ParentComponent.js
文件。
ChildComponent.js
代码如下:
import React from'react';
function ChildComponent(props) {
const handleClick = () => {
props.onChildClick('Data from child');
};
return (
<button onClick={handleClick}>Click me to send data to parent</button>
);
}
export default ChildComponent;
ParentComponent.js
代码如下:
import React from'react';
import ChildComponent from './ChildComponent';
function ParentComponent() {
const handleChildData = (data) => {
console.log('Received data from child:', data);
};
return (
<div>
<ChildComponent onChildClick={handleChildData} />
</div>
);
}
export default ParentComponent;
在这个例子中,父组件 ParentComponent
向子组件 ChildComponent
传递了一个 onChildClick
回调函数。子组件在按钮点击时调用这个回调函数,并传递数据 Data from child
,父组件通过 handleChildData
函数接收并处理这个数据。
兄弟组件通信
兄弟组件之间的通信通常需要借助共同的父组件。即通过父组件作为中间桥梁来传递数据。例如,有 ComponentA
和 ComponentB
两个兄弟组件,它们的父组件为 ParentComponent
。ComponentA
可以将数据传递给 ParentComponent
,然后 ParentComponent
再将数据传递给 ComponentB
。
首先创建 ComponentA.js
:
import React from'react';
function ComponentA(props) {
const handleClick = () => {
props.onDataChange('Data from ComponentA');
};
return (
<button onClick={handleClick}>Send data to ComponentB</button>
);
}
export default ComponentA;
然后创建 ComponentB.js
:
import React from'react';
function ComponentB(props) {
return (
<div>
<p>Received data: {props.data}</p>
</div>
);
}
export default ComponentB;
最后修改 ParentComponent.js
来协调它们之间的通信:
import React, { useState } from'react';
import ComponentA from './ComponentA';
import ComponentB from './ComponentB';
function ParentComponent() {
const [sharedData, setSharedData] = useState('');
const handleDataChange = (data) => {
setSharedData(data);
};
return (
<div>
<ComponentA onDataChange={handleDataChange} />
<ComponentB data={sharedData} />
</div>
);
}
export default ParentComponent;
在这个例子中,ComponentA
通过 onDataChange
回调函数将数据传递给 ParentComponent
,ParentComponent
通过 setSharedData
更新 sharedData
状态,然后将 sharedData
作为 props
传递给 ComponentB
,从而实现了兄弟组件之间的通信。
跨层级组件通信(Context)
当组件层级较深,数据需要在多个层级的组件之间传递时,使用 props
层层传递会变得繁琐。这时可以使用 React 的 Context 来实现跨层级组件通信。
首先,在 src
文件夹下创建一个 MyContext.js
文件,用于定义 Context:
import React from'react';
const MyContext = React.createContext();
export default MyContext;
然后,在需要共享数据的父组件中,使用 MyContext.Provider
来提供数据。修改 App.js
如下:
import React from'react';
import logo from './logo.svg';
import './App.css';
import MyContext from './MyContext';
function App() {
const sharedValue = 'This is shared data';
return (
<MyContext.Provider value={sharedValue}>
<div className="App">
<header className="App - header">
<img src={logo} className="App - logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App - link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
</MyContext.Provider>
);
}
export default App;
在子组件中,可以通过 MyContext.Consumer
来消费这个共享数据。在 components
文件夹下创建 DeepChildComponent.js
文件:
import React from'react';
import MyContext from '../MyContext';
function DeepChildComponent() {
return (
<MyContext.Consumer>
{value => (
<div>
<p>Received shared data: {value}</p>
</div>
)}
</MyContext.Consumer>
);
}
export default DeepChildComponent;
这样,即使 DeepChildComponent
与 App
组件之间有多层嵌套,也可以直接获取到共享的数据。
路由(Routing)
在单页应用(SPA)中,路由是非常重要的概念,它允许我们根据不同的 URL 展示不同的内容。在 React 应用中,我们通常使用 react - router - dom
库来实现路由功能。
安装 react - router - dom
首先,在项目根目录下使用以下命令安装 react - router - dom
:
npm install react - router - dom
基本路由设置
安装完成后,在 src
文件夹下创建一个 routes
文件夹,用于存放路由相关的代码。在 routes
文件夹中创建 AppRoutes.js
文件。代码如下:
import React from'react';
import { BrowserRouter as Router, Routes, Route } from'react - router - dom';
import Home from '../components/Home';
import About from '../components/About';
function AppRoutes() {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Router>
);
}
export default AppRoutes;
在这段代码中,我们首先从 react - router - dom
中导入了 BrowserRouter
(这里使用别名 Router
)、Routes
和 Route
。BrowserRouter
为应用提供了路由的上下文环境,Routes
用于定义一组路由,Route
用于定义具体的路由规则。每个 Route
组件通过 path
属性指定路径,通过 element
属性指定该路径对应的组件。
假设我们在 components
文件夹下创建了 Home.js
和 About.js
组件,代码如下:
Home.js
:
import React from'react';
function Home() {
return (
<div>
<h1>Home Page</h1>
</div>
);
}
export default Home;
About.js
:
import React from'react';
function About() {
return (
<div>
<h1>About Page</h1>
</div>
);
}
export default About;
最后,在 App.js
中引入 AppRoutes
:
import React from'react';
import logo from './logo.svg';
import './App.css';
import AppRoutes from './routes/AppRoutes';
function App() {
return (
<div className="App">
<AppRoutes />
</div>
);
}
export default App;
这样,当我们在浏览器中访问 http://localhost:3000/
时,会显示 Home Page
,访问 http://localhost:3000/about
时,会显示 About Page
。
动态路由
动态路由允许我们在 URL 中传递参数。例如,我们可能需要根据不同的用户 ID 展示不同的用户信息页面。修改 AppRoutes.js
如下:
import React from'react';
import { BrowserRouter as Router, Routes, Route } from'react - router - dom';
import Home from '../components/Home';
import About from '../components/About';
import User from '../components/User';
function AppRoutes() {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/user/:id" element={<User />} />
</Routes>
</Router>
);
}
export default AppRoutes;
在 components
文件夹下创建 User.js
组件,代码如下:
import React from'react';
import { useParams } from'react - router - dom';
function User() {
const { id } = useParams();
return (
<div>
<h1>User Page - {id}</h1>
</div>
);
}
export default User;
在这个例子中,我们通过 useParams
Hook 从 URL 中获取 id
参数,并在页面中显示出来。当我们访问 http://localhost:3000/user/123
时,会显示 User Page - 123
。
状态管理(State Management)
随着应用规模的增大,组件之间的状态管理会变得复杂。React 提供了一些方式来管理应用的状态,如 Redux 和 MobX 等。这里我们以 Redux 为例进行介绍。
安装 Redux 和 react - redux
在项目根目录下使用以下命令安装:
npm install redux react - redux
Redux 基本概念
Redux 有三个核心概念:store
、action
和 reducer
。
- Store:
store
是 Redux 应用的状态容器,它保存着整个应用的状态。一个 Redux 应用只有一个store
。 - Action:
action
是一个普通的 JavaScript 对象,用于描述发生的事件。它必须有一个type
属性来表示事件的类型。 - Reducer:
reducer
是一个纯函数,它接受当前的state
和一个action
作为参数,并返回一个新的state
。
配置 Redux
在 src
文件夹下创建一个 redux
文件夹,在其中创建 store.js
文件,用于配置 store
:
import { createStore } from'redux';
import rootReducer from './reducers';
const store = createStore(rootReducer);
export default store;
然后在 redux
文件夹下创建 reducers
文件夹,并在其中创建 rootReducer.js
文件,代码如下:
import { combineReducers } from'redux';
const initialState = {
counter: 0
};
function counterReducer(state = initialState, action) {
switch (action.type) {
case 'INCREMENT':
return {
...state,
counter: state.counter + 1
};
case 'DECREMENT':
return {
...state,
counter: state.counter - 1
};
default:
return state;
}
}
const rootReducer = combineReducers({
counterReducer
});
export default rootReducer;
在这个例子中,我们定义了一个 counterReducer
来管理 counter
状态。combineReducers
用于将多个 reducer
合并成一个 rootReducer
。
在 React 组件中使用 Redux
在 App.js
中引入 store
并使用 Provider
组件将 store
提供给整个应用:
import React from'react';
import logo from './logo.svg';
import './App.css';
import { Provider } from'react - redux';
import store from './redux/store';
import CounterComponent from './components/CounterComponent';
function App() {
return (
<Provider store={store}>
<div className="App">
<CounterComponent />
</div>
</Provider>
);
}
export default App;
在 components
文件夹下创建 CounterComponent.js
文件,代码如下:
import React from'react';
import { useSelector, useDispatch } from'react - redux';
function CounterComponent() {
const counter = useSelector(state => state.counterReducer.counter);
const dispatch = useDispatch();
const increment = () => {
dispatch({ type: 'INCREMENT' });
};
const decrement = () => {
dispatch({ type: 'DECREMENT' });
};
return (
<div>
<p>Counter: {counter}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
}
export default CounterComponent;
在 CounterComponent
中,我们使用 useSelector
Hook 来获取 store
中的 counter
状态,使用 useDispatch
Hook 来获取 dispatch
函数,通过 dispatch
函数触发 action
来更新 state
。
通过以上步骤,我们就完成了一个基于 Redux 的状态管理示例。在实际应用中,Redux 可以帮助我们更好地管理复杂的应用状态,提高代码的可维护性和可扩展性。
性能优化
在 React 应用开发中,性能优化是非常重要的环节。以下是一些常见的性能优化方法。
使用 React.memo
React.memo
是一个高阶组件,它可以对函数组件进行性能优化。它会对组件的 props
进行浅比较,如果 props
没有变化,则不会重新渲染组件。例如:
import React from'react';
const MyComponent = React.memo((props) => {
return (
<div>
<p>{props.value}</p>
</div>
);
});
export default MyComponent;
在这个例子中,如果 props.value
没有变化,MyComponent
不会重新渲染。
shouldComponentUpdate(类组件)
在类组件中,可以通过重写 shouldComponentUpdate
方法来控制组件是否需要重新渲染。该方法接收 nextProps
和 nextState
作为参数,返回一个布尔值。如果返回 false
,组件将不会重新渲染。例如:
import React, { Component } from'react';
class MyClassComponent extends Component {
shouldComponentUpdate(nextProps, nextState) {
return this.props.value!== nextProps.value;
}
render() {
return (
<div>
<p>{this.props.value}</p>
</div>
);
}
}
export default MyClassComponent;
在这个例子中,只有当 props.value
发生变化时,组件才会重新渲染。
使用 useCallback 和 useMemo
useCallback
用于缓存函数,useMemo
用于缓存值。它们可以避免在组件每次渲染时都重新创建函数或计算值。例如:
import React, { useCallback, useMemo } from'react';
function MyFunctionComponent() {
const expensiveCalculation = () => {
// 进行复杂计算
return 1 + 2 + 3 + 4 + 5;
};
const memoizedValue = useMemo(expensiveCalculation, []);
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []);
return (
<div>
<p>Memoized value: {memoizedValue}</p>
<button onClick={handleClick}>Click me</button>
</div>
);
}
export default MyFunctionComponent;
在这个例子中,expensiveCalculation
函数只会在组件挂载时执行一次,handleClick
函数也只会在组件挂载时创建一次。
代码分割(Code Splitting)
随着应用的增长,打包后的文件可能会变得非常大,影响加载性能。代码分割可以将代码按需加载,提高应用的加载速度。在 React 中,可以使用动态 import()
来实现代码分割。例如:
import React, { Suspense } from'react';
const MyLazyComponent = React.lazy(() => import('./MyLazyComponent'));
function App() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<MyLazyComponent />
</Suspense>
</div>
);
}
export default App;
在这个例子中,MyLazyComponent
组件只有在需要渲染时才会被加载,Suspense
组件用于在组件加载时显示加载提示。
通过以上性能优化方法,可以有效地提升 React 应用的性能,为用户提供更好的体验。在实际开发中,需要根据应用的具体情况选择合适的优化方法。
通过以上内容,我们全面地学习了如何搭建第一个 React 应用,从环境搭建、项目结构剖析,到组件编写、用户输入处理、组件间通信、路由设置、状态管理以及性能优化等方面进行了详细的介绍。希望这些知识能够帮助你快速上手 React 开发,并在实际项目中灵活运用。