如何在React中创建自定义组件

来自菜鸟教程
跳转至:导航、​搜索

作为 Write for DOnations 计划的一部分,作者选择了 Creative Commons 来接受捐赠。

介绍

在本教程中,您将学习在 React 中创建自定义 组件。 组件是可以在应用程序中重用的独立功能,是所有 React 应用程序的构建块。 通常,它们可以是简单的 JavaScript 函数,但您可以将它们当作自定义的 HTML 元素使用。 按钮、菜单和任何其他前端页面内容都可以创建为组件。 组件还可以包含状态信息和显示降价。

在学习了如何在 React 中创建组件之后,您将能够将复杂的应用程序拆分成更易于构建和维护的小块。

在本教程中,您将创建一个表情符号列表,在点击时将显示其名称。 表情符号将使用自定义组件构建,并将从另一个自定义组件内部调用。 在本教程结束时,您将使用 JavaScript 类和 JavaScript 函数制作自定义组件,并且您将了解如何将现有代码分成可重用的部分以及如何将组件存储在可读的文件结构中。

先决条件

第 1 步 — 设置 React 项目

在这一步中,您将使用 Create React App 为您的项目创建一个基础。 您还将通过映射表情符号列表并添加少量样式来修改默认项目以创建基础项目。

首先,创建一个新项目。 打开终端,然后运行以下命令:

npx create-react-app tutorial-03-component

完成后,进入项目目录:

cd tutorial-03-component

在文本编辑器中打开 App.js 代码:

nano src/App.js

接下来,取出 Create React App 创建的模板代码,然后将内容替换为显示表情符号列表的新 React 代码:

tutorial-03-component/src/App.js

import React from 'react';
import './App.css';

const displayEmojiName = event => alert(event.target.id);
const emojis = [
  {
    emoji: '😀',
    name: "test grinning face"
  },
  {
    emoji: '🎉',
    name: "party popper"
  },
  {
    emoji: '💃',
    name: "woman dancing"
  }
];

function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

此代码使用 JSX 语法在 emojis arraymap() 并将它们列为 <li> 列表项。 它还附加了 onClick events 以在浏览器中显示表情符号数据。 要更详细地研究代码,请查看 How to Create React Elements with JSX,其中包含对 JSX 的详细说明。

保存并关闭文件。 您现在可以删除 logo.svg 文件,因为它是模板的一部分并且您不再引用它:

rm src/logo.svg

现在,更新样式。 打开src/App.css

nano src/App.css

将内容替换为以下 CSS 以使元素居中并调整字体:

tutorial-03-component/src/App.css

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

button {
    font-size: 2em;
    border: 0;
    padding: 0;
    background: none;
    cursor: pointer;
}

ul {
    display: flex;
    padding: 0;
}

li {
    margin: 0 20px;
    list-style: none;
    padding: 0;
}

这使用 flex 使主要 <h1> 居中并列出元素。 它还删除了默认按钮样式和 <li> 样式,以便表情符号排成一行。 更多细节可以在 如何使用 JSX 创建 React 元素中找到。

保存并退出文件。

在项目的根目录中打开另一个终端窗口。 使用以下命令启动项目:

npm start

命令运行后,您将在 Web 浏览器中的 http://localhost:3000 中看到该项目正在运行。

在您处理项目的整个过程中保持运行。 每次保存项目时,浏览器都会自动刷新并显示最新的代码。

您将看到带有 Hello, World 和您在 App.js 文件中列出的三个表情符号的项目页面:

现在您已经设置了代码,现在可以开始在 React 中组合组件。

第 2 步 — 使用 React 类创建独立组件

现在您的项目正在运行,您可以开始制作您的自定义组件。 在这一步中,您将通过扩展基础 React Component 创建一个独立的 React 组件。 您将创建一个新类、添加方法并使用渲染函数来显示数据。

React 组件是独立的元素,您可以在整个页面中重用它们。 通过制作小而专注的代码片段,您可以随着应用程序的增长移动和重用片段。 这里的关键是它们是独立的和专注的,允许您将代码分离成逻辑片段。 事实上,您已经在使用逻辑分离的组件:App.js 文件是一个功能组件,您将在第 3 步中看到更多内容。

自定义组件有两种类型:基于类的功能。 您要制作的第一个组件是基于类的组件。 您将创建一个名为 Instructions 的新组件,用于解释表情符号查看器的说明。

注意: 基于类的组件曾经是最流行的创建 React 组件的方式。 但是随着 React Hooks 的引入,许多开发人员和库正在转向使用函数式组件。

尽管功能组件现在已成为常态,但您经常会在遗留代码中找到类组件。 你不需要使用它们,但你需要知道如何识别它们。 他们还清楚地介绍了许多未来的概念,例如状态管理。 在本教程中,您将学习制作类和函数式组件。


首先,创建一个新文件。 按照惯例,组件文件大写:

touch src/Instructions.js

然后在文本编辑器中打开文件:

nano src/Instructions.js

首先,导入 ReactComponent 类并使用以下行导出 Instructions

tutorial-03-component/src/Instructions.js

import React, { Component } from 'react';

export default class Instructions extends Component {}

导入 React 将转换 JSX。 Component 是一个基类,您将对其进行扩展以创建您的组件。 为了扩展它,您创建了一个具有组件名称 (Instructions) 的类,并使用 export 行扩展了基础 Component。 您还将在类声明的开头使用 export default 关键字将此类导出为默认值。

类名应该大写并且应该与文件名匹配。 这在使用调试工具时很重要,它将显示组件的名称。 如果名称与文件结构匹配,将更容易找到相关组件。

基础 Component 类具有 几种方法 您可以在自定义类中使用。 最重要的方法,也是您将在本教程中使用的唯一方法,是 render() 方法。 render() 方法返回要在浏览器中显示的 JSX 代码。

首先,在 <p> 标签中添加对该应用程序的一些说明:

tutorial-03-component/src/Instructions.js

import React, { Component } from 'react';

export class Instructions extends Component {

  render() {
    return(
      <p>Click on an emoji to view the emoji short name.</p>
    )
  }

}

保存并关闭文件。 此时,您的浏览器仍然没有任何变化。 那是因为您还没有使用新组件。 要使用该组件,您必须将其添加到另一个连接到根组件的组件中。 在本项目中,<App>index.js 中的根组件。 要让它出现在您的应用程序中,您需要添加到 <App> 组件。

在文本编辑器中打开 src/App.js

nano src/App.js

首先,您需要导入组件:

tutorial-03-component/src/App.js

import React from 'react';

import Instructions from './Instructions';

import './App.css';

...

export default App;

由于它是默认导入,因此您可以导入任何您想要的名称。 为了便于阅读,最好保持名称一致——导入应该与组件名称匹配,而组件名称应该与文件名匹配——但唯一的固定规则是组件必须以大写字母开头。 这就是 React 知道它是 一个 React 组件 的方式。

现在您已经导入了该组件,将其添加到您的其余代码中,就好像它是一个自定义 HTML 元素一样:

tutorial-03-component/src/App.js

import React from 'react';

import Instructions from './Instructions.js'

...
function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <Instructions />
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

在此代码中,您使用尖括号包裹了组件。 由于该组件没有任何子组件,因此它可以通过以 /> 结尾来自动关闭。

保存文件。 当您这样做时,页面将刷新,您将看到新组件。

现在您有了一些文本,您可以添加图像。 从 wikimedia 下载表情符号图像,并使用以下命令将其保存在 src 目录中为 emoji.svg

curl -o src/emoji.svg https://upload.wikimedia.org/wikipedia/commons/3/33/Twemoji_1f602.svg

curl 向 URL 发出请求,-o 标志允许您将文件保存为 src/emoji.svg

接下来,打开您的组件文件:

nano src/Instructions.js

导入表情符号并使用动态链接将其添加到您的自定义组件中:

tutorial-03-component/src/Instructions.js

import React, { Component } from 'react';
import emoji from './emoji.svg'

export default class Instructions extends Component {

  render() {
    return(
      <>
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </>
    )
  }
}

请注意,您需要在导入时包含文件扩展名 .svg。 导入时,您正在导入由 webpack 在代码编译时创建的动态路径。 有关更多信息,请参阅 如何使用 Create React App 设置 React 项目。

您还需要用空标签包装 <img><p> 标签,以确保返回单个元素。

保存文件。 重新加载时,与其余内容相比,图像会非常大:

要使图像更小,您需要向自定义组件添加一些 CSS 和 className

首先,在 Instructions.js 中,将空标签更改为 div,并给它一个 instructionsclassName

tutorial-03-component/src/Instructions.js

import React, { Component } from 'react';
import emoji from './emoji.svg'

export default class Instructions extends Component {

  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

保存并关闭文件。 接下来打开App.css

nano src/App.css

.instructions 类选择器 创建规则:

tutorial-03-component/src/App.css

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

...

.instructions {
    display: flex;
    flex-direction: column;
    align-items: center;
}

当您添加 flex 样式的 display 时,会使 imgpflexbox 为中心。 您更改了方向,使所有内容都与 flex-direction: column; 垂直排列。 align-items: center; 行将使元素在屏幕上居中。

现在您的元素已排列好,您需要更改图像大小。 给 div 中的 img 一个 width100pxheight

tutorial-03-component/src/App.css

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

...

.instructions {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.instructions img {
    width: 100px;
    height: 100px;
}

保存并关闭文件。 浏览器将重新加载,您会看到图像要小得多:

至此,您已经创建了一个独立且可重用的自定义组件。 要查看它的可重用性,请将第二个实例添加到 App.js

打开App.js

nano src/App.js

App.js 中,添加组件的第二个实例:

tutorial-03-component/src/App.js

import React from 'react';

import Instructions from './Instructions.js'

...

function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <Instructions />
      <Instructions />
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

保存文件。 当浏览器重新加载时,您将看到该组件两次。

在这种情况下,您不希望有两个 Instructions 实例,但您可以看到该组件可以有效地重用。 当您创建自定义按钮或表格时,您可能会在一个页面上多次使用它们,这使得它们非常适合自定义组件。

现在,您可以删除额外的图像标签。 在您的文本编辑器中,删除第二个 <Instructions /> 并保存文件:

tutorial-03-component/src/App.js

import React from 'react';

import Instructions from './Instructions.js'

...

function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <Instructions />
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

现在您有了一个可重用的独立组件,您可以多次将其添加到父组件中。 您现在拥有的结构适用于少量组件,但存在一个小问题。 所有文件都混合在一起。 <Instructions> 的图像与 <App> 的资产位于同一目录中。 您还将 <App> 的 CSS 代码与 <Instructions> 的 CSS 混合。

在下一步中,您将创建一个文件结构,通过将每个组件的功能、样式和依赖项组合在一起来赋予每个组件独立性,从而使您能够根据需要移动它们。

第三步——创建一个可读的文件结构

在此步骤中,您将创建一个文件结构来组织您的组件及其资产,例如图像、CSS 和其他 JavaScript 文件。 您将按组件而不是资产类型对代码进行分组。 换句话说,您不会有一个单独的目录来存放 CSS、图像和 JavaScript。 相反,每个组件都有一个单独的目录,其中包含相关的 CSS、JavaScript 和图像。 在这两种情况下,你都是分离关注点

由于您有一个独立的组件,因此您需要一个对相关代码进行分组的文件结构。 目前,所有内容都在同一个目录中。 列出 src 目录中的项目:

ls src/

输出将显示事情变得非常混乱:

OutputApp.css                 Instructions.js         index.js
App.js                  emoji.svg               serviceWorker.js
App.test.js             index.css               setupTests.js

您的根组件(index.cssindex.js) 和您的自定义组件 Instructions.js

React 是 故意不可知论 关于文件结构。 它不推荐特定的结构,并且该项目可以使用各种不同的文件层次结构。 但是我们建议添加一些顺序,以避免在根目录中出现难以导航的组件、CSS 文件和图像。 此外,显式命名可以更容易地查看项目的哪些部分是相关的。 例如,一个名为 Logo.svg 的图像文件可能不是一个名为 Header.js 的组件的一部分。

最简单的结构之一是创建一个 components 目录,其中每个组件都有一个单独的目录。 这将允许您将组件与配置代码分开分组,例如 serviceWorker,同时将资产与组件分组。

创建 Components 目录

首先,创建一个名为 components 的目录:

mkdir src/components

接下来,将以下组件和代码移动到目录中:App.cssApp.jsApp.test.jsInstructions.jsemoji.svg

mv src/App.* src/components/
mv src/Instructions.js src/components/
mv src/emoji.svg src/components/

在这里,您使用 通配符 (*) 来选择所有以 App. 开头的文件。

移动代码后,您将在运行 npm start 的终端中看到错误。

OutputFailed to compile.

./src/App.js
Error: ENOENT: no such file or directory, open 'your_file_path/tutorial-03-component/src/App.js'

请记住,所有代码都是使用相对路径导入的。 如果更改某些文件的路径,则需要更新代码。

为此,打开 index.js

nano src/index.js

然后将App导入的路径改为从components/目录导入。

tutorial-03-component/src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App';
import * as serviceWorker from './serviceWorker';

...

serviceWorker.unregister();

保存并关闭文件。 您的脚本将检测到更改并且错误将消失。

现在您在单独的目录中拥有组件。 随着您的应用程序变得越来越复杂,您可能拥有 API 服务、数据存储和实用程序函数的目录。 分离组件代码是第一步,但您仍然在 App.css 文件中混合了 Instructions 的 CSS 代码。 要创建这种逻辑分离,您首先将组件移动到单独的目录中。

将组件移动到单个目录

首先,为 <App> 组件创建一个目录:

mkdir src/components/App

然后将相关文件移动到新目录中:

mv src/components/App.* src/components/App

当你这样做时,你会得到与上一节类似的错误:

OutputFailed to compile.

./src/components/App.js
Error: ENOENT: no such file or directory, open 'your_file_path/tutorial-03-component/src/components/App.js'

在这种情况下,您需要更新两件事。 首先,您需要更新 index.js 中的路径。

打开index.js文件:

nano src/index.js

然后更新App的导入路径指向App目录下的App组件。

tutorial-03-component/src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App/App';
import * as serviceWorker from './serviceWorker';

...

serviceWorker.unregister();

保存并关闭文件。 该应用程序仍然无法运行。 你会看到这样的错误:

OutputFailed to compile.

./src/components/App/App.js

Module not found: Can't resolve './Instructions.js' in 'your_file_path/tutorial-03-component/src/components/App'

由于 <Instructions><App> 组件不在同一目录级别,因此您需要更改导入路径。 在此之前,为 Instructions 创建一个目录。 在 src/components 目录下创建一个名为 Instructions 的目录:

mkdir src/components/Instructions

然后将 Instructions.jsemoji.svg 移动到该目录中:

mv src/components/Instructions.js src/components/Instructions
mv src/components/emoji.svg src/components/Instructions

现在已经创建了 Instructions 组件目录,您可以完成更新文件路径以将您的组件连接到您的应用程序。

更新 import 路径

现在组件位于单独的目录中,您可以在 App.js 中调整导入路径。

打开App.js

nano src/components/App/App.js

由于路径是相对的,您需要向上移动一个目录 - src/components - 然后进入 Instructions.jsInstructions 目录,但由于这是一个 JavaScript 文件,您不需要最终导入。

tutorial-03-component/src/components/App/App.js

import React from 'react';

import Instructions from '../Instructions/Instructions.js';

import './App.css';

...

export default App;

保存并关闭文件。 现在您的导入都使用正确的路径,您的浏览器将更新并显示应用程序。

注:也可以调用各个目录下的根文件index.js。 例如,您可以创建 src/components/App/index.js 而不是 src/components/App/App.js。 这样做的好处是您的进口量略小。 如果路径指向目录,则导入将查找 index.js 文件。 src/index.js 文件中 src/components/App/index.js 的导入将是 import ./components/App。 这种方法的缺点是您有很多同名的文件,这会使某些文本编辑器难以阅读。 最终,这是个人和团队的决定,但最好保持一致。


在共享文件中分离代码

现在每个组件都有自己的目录,但并非所有内容都是完全独立的。 最后一步是将 Instructions 的 CSS 提取到单独的文件中。

首先,在src/components/Instructions中创建一个CSS文件:

touch src/components/Instructions/Instructions.css

接下来,在文本编辑器中打开 CSS 文件:

nano src/components/Instructions/Instructions.css

添加您在前面部分中创建的说明 CSS:

tutorial-03-component/src/components/Instructions/Instructions.css

.instructions {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.instructions img {
    width: 100px;
    height: 100px;
}

保存并关闭文件。 接下来,从 src/components/App/App.css 中删除指令 CSS。

nano src/components/App/App.css

删除关于 .instructions 的行。 最终文件将如下所示:

tutorial-03-component/src/components/App/App.css

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

button {
    font-size: 2em;
    border: 0;
    padding: 0;
    background: none;
    cursor: pointer;
}

ul {
    display: flex;
    padding: 0;
}

li {
    margin: 0 20px;
    list-style: none;
    padding: 0;
}

保存并关闭文件。 最后,在Instructions.js中导入CSS:

nano src/components/Instructions/Instructions.js

使用相对路径导入 CSS:

tutorial-03-component/src/components/Instructions/Instructions.js

import React, { Component } from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default class Instructions extends Component {

  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

保存并关闭文件。 您的浏览器窗口将看起来像以前一样,除了现在所有文件资产都分组在同一个目录中。

现在,最后看一下结构。 一、src/目录:

ls src

components/ 目录和实用程序文件(例如 serviceWorker.jssetupTests.js)旁边有根组件 index.js 和相关的 CSS index.css

Outputcomponents              serviceWorker.js
index.css               setupTests.js
index.js

接下来,查看 components 内部:

ls src/components

您将看到每个组件的目录:

OutputApp             Instructions

如果您查看每个组件的内部,您将看到组件代码、CSS、测试和图像文件(如果存在)。

ls src/components/App
OutputApp.css         App.js          App.test.js
ls src/components/Instructions
OutputInstructions.css        Instructions.js         emoji.svg

至此,您已经为您的项目创建了一个坚实的结构。 你移动了很多代码,但是现在你有了一个结构,它会更容易扩展。

这不是组成结构的唯一方法。 某些文件结构可以通过指定将拆分为不同包的目录来利用 代码拆分 。 其他文件结构 由路由 拆分,并为跨路由使用的组件使用公共目录。

现在,坚持使用不太复杂的方法。 随着对另一种结构的需求出现,从简单到复杂总是更容易。 在需要之前从复杂结构开始会使重构变得困难。

现在您已经创建并组织了一个基于类的组件,下一步您将创建一个功能组件。

第 4 步 - 构建功能组件

在此步骤中,您将创建一个功能组件。 函数式组件是当代 React 代码中最常见的组件。 这些组件往往更短,并且与基于类的组件不同,它们可以使用 React hooks,一种新的状态和事件管理形式。

函数式组件是返回一些 JSX 的 JavaScript 函数。 它不需要扩展任何东西,也没有特殊的方法可以记住。

要将 <Instructions> 重构为函数式组件,您需要将类更改为函数并删除 render 方法,以便只剩下 return 语句。

为此,首先在文本编辑器中打开 Instructions.js

nano src/components/Instructions/Instructions.js

class 声明更改为 function 声明:

tutorial-03-component/src/components/Instructions/Instructions.js

import React, { Component } from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default function Instructions() {
  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

接下来,删除 { Component } 的导入:

tutorial-03-component/src/components/Instructions/Instructions.js

import React from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default function Instructions() {

  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

最后,删除 render() 方法。 那时,您只返回 JSX。

tutorial-03-component/src/components/Instructions/Instructions.js

import React from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default function Instructions() {
  return(
    <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
    </div>
  )
}

保存文件。 浏览器将刷新,您将看到与以前一样的页面。

您还可以使用隐式返回将该函数重写为 箭头函数 。 主要区别在于您丢失了函数体。 您还需要首先将函数分配给一个变量,然后导出该变量:

tutorial-03-component/src/components/Instructions/Instructions.js

import React from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

const Instructions = () => (
  <div className="instructions">
    <img alt="laughing crying emoji" src={emoji} />
    <p>Click on an emoji to view the emoji short name.</p>
  </div>
)

export default Instructions;

简单的功能组件和基于类的组件非常相似。 当你有一个不存储状态的简单组件时,最好使用函数式组件。 两者之间的真正区别在于您如何存储组件的状态和使用属性。 基于类的组件使用方法和属性来设置状态,并且往往会更长一些。 功能组件使用钩子来存储状态或管理更改,并且往往更短一些。

结论

现在你有了一个带有独立部分的小应用程序。 您创建了两种主要类型的组件:函数式和类。 您将组件的一部分分离到目录中,以便您可以将相似的代码段组合在一起。 您还导入并重用了这些组件。

了解组件后,您可以开始将应用程序视为可以拆开并重新组合在一起的部分。 项目变得模块化和可互换。 将整个应用程序视为一系列组件的能力是在 React 中思考的重要一步。 如果您想查看更多 React 教程,请查看我们的 React 主题页面,或返回 如何在 React.js 中编码系列页面