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

_ 作者选择了 Creative Commons以作为 Write for Donations计划的一部分接收捐款。

介绍

在此教程中, 您可以在 [React] ([ LINK0] ) 中学习创建自定义 _ 组件_ 。 组件是应用程序中可以再利用的独立功能块,也是所有React应用程序的构件. 通常,它们可以是简单的JavaScript函数和[类 (https://andsky.com/tech/tutorials/understanding-classes-in-javascript),但您使用它们时却好像它们是定制的HTML元素. 按钮,菜单和任何其他前端页面内容都可以作为组件来创建. 组件还可以包含状态信息并显示减号.

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

在本教程中,你将创建一个列表的情感符号,将显示他们的名称点击. 这些情感符号将使用自定义组件构建,并将从另一个自定义组件的内部调用。 在本教程结束时,你将使用JavaScript类和JavaScript功能来创建自定义组件,你将了解如何将现有的代码分离成可重复使用的部件,以及如何将组件存储在可读的文件结构中。

前提条件

  • 联合国 您需要运行一个开发环境 [Node.js] (https://nodejs.org/en/about/); 此教程在Node.js 版本10.20.1和npm 版本6.14.4. 上进行了测试. 要在 macOS 或 Ubuntu 18.04 上安装此功能,请遵循 [如何在 macOS (https://andsky.com/tech/tutorials/how-to-install-node-js-and-create-a-local-development-environment-on-macos 上安装节点并创建本地开发环境] 或 [如何在 Ubuntu 18.04 (https://andsky.com/tech/tutorials/how-to-install-node-js-on-ubuntu-18-04 上安装节点.js] 的 ** 部分使用 PPA
  • 联合国 您需要能够使用 [创建回放 App] (https://github.com/facebook/create-react-app) 创建应用程序 。 您可以在 [How To Set up a React Project with Create React App] (https://andsky.com/tech/tutorials/how-to-set-up-a-react-project-with-create-react-app ) 找到使用 Create React App 安装应用程序的指令.
  • 联合国 您将使用 JSX 语法, 您可以在 [如何与 JSX 创建元素( https://andsky.com/tech/tutorials/how-to-create-react-elements-with-jsx) 教程中了解 。
  • 联合国 您还需要关于 JavaScript 的基本知识, 您可以在 [How To Code in JavaScript] (https://www.digitalocean.com/community/tutorial_series/how-to-code-in-javascript] 中找到, 同时您还需要关于 HTML 和 CSS 的基本知识 。 HTML和CSS的好资源是Mozilla开发者网络. .

步骤 1 – 设置 React 项目

在此步骤中,您将使用Create React App为您的项目创建一个基础,您还将修改默认项目以创建您的基础项目,通过对情感符列表进行映射并添加少量风格。

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

1npx create-react-app tutorial-03-component

一旦完成,转到项目目录:

1cd tutorial-03-component

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

1nano src/App.js

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

 1[label tutorial-03-component/src/App.js]
 2import React from 'react';
 3import './App.css';
 4
 5const displayEmojiName = event => alert(event.target.id);
 6const emojis = [
 7  {
 8    emoji: '😀',
 9    name: "test grinning face"
10  },
11  {
12    emoji: '🎉',
13    name: "party popper"
14  },
15  {
16    emoji: '💃',
17    name: "woman dancing"
18  }
19];
20
21function App() {
22  const greeting = "greeting";
23  const displayAction = false;
24  return(
25    <div className="container">
26      <h1 id={greeting}>Hello, World</h1>
27      {displayAction && <p>I am writing JSX</p>}
28      <ul>
29        {
30          emojis.map(emoji => (
31            <li key={emoji.name}>
32              <button
33                onClick={displayEmojiName}
34              >
35                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
36              </button>
37            </li>
38          ))
39        }
40      </ul>
41    </div>
42  )
43}
44
45export default App;

本代码在emojis'[阵 (https://andsky.com/tech/tutorials/understanding-arrays-in-javascript)上使用JSX语法[map ()' (https://andsky.com/tech/tutorials/how-to-use-array-methods-in-javascript-iteration-methods# map(),并将其列为QQLi>` 列表项目。 它还附上了 " onClick " 事件,以便在浏览器中显示emoji数据。 为了更详细地探索代码,请检查如何与JSX创建反应元素,其中包含了对JSX的详细解释.

现在你可以删除 logo.svg 文件,因为它是模板的一部分,而你不再引用它:

1rm src/logo.svg

现在,更新风格。打开src/App.css:

1nano src/App.css

用以下 CSS 替换内容以中心元素并调整字体:

 1[label tutorial-03-component/src/App.css]
 2.container {
 3    display: flex;
 4    flex-direction: column;
 5    align-items: center;
 6}
 7
 8button {
 9    font-size: 2em;
10    border: 0;
11    padding: 0;
12    background: none;
13    cursor: pointer;
14}
15
16ul {
17    display: flex;
18    padding: 0;
19}
20
21li {
22    margin: 0 20px;
23    list-style: none;
24    padding: 0;
25}

它还删除默认按钮风格和

  • 风格,以便情感片排列一排。 更多细节可以在 How to Create React Elements with JSX找到。

    保存和退出文件。

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

    1npm start
    

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

    每次您保存该项目,浏览器将自动更新并显示最新的代码。

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

    Browser with emoji

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

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

    在此步骤中,您将创建一个独立的 React 组件,通过扩展基层 React Component class来创建一个新类,添加方法,并使用渲染功能来显示数据。

    React 组件是您可以在页面上重复使用的自含元素,通过制作小型、聚焦的代码,您可以随着应用程序的增长而移动和重复使用部分。 这里的关键是它们是自含和聚焦的,允许您将代码分离成逻辑部分。 事实上,您已经在与逻辑上分离的组件一起工作:App.js文件是一个功能组件,您将在步骤 3 中看到更多。

    有两种类型的自定义组件: class-basedfunctional. 您要创建的第一个组件是基于类的组件. 您将创建一个名为指令的新组件,该组件解释了情感片浏览器的说明。

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

    虽然功能组件现在是常见的,但您通常会在传统代码中找到类组件. 您不需要使用它们,但您确实需要知道如何识别它们。

    要开始,创建一个新的文件. 根据惯例,组件文件被资本化:

    1touch src/Instructions.js
    

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

    1nano src/Instructions.js
    

    首先,输入反应组件类,然后输出说明与以下行:

    1[label tutorial-03-component/src/Instructions.js]
    2import React, { Component } from 'react';
    3
    4export default class Instructions extends Component {}
    

    导入)的类别,并将基层Component扩展到export行。

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

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

    首先,在一个<p>标签中添加一个应用程序的解释:

     1[label tutorial-03-component/src/Instructions.js]
     2import React, { Component } from 'react';
     3
     4export class Instructions extends Component {
     5
     6  render() {
     7    return(
     8      <p>Click on an emoji to view the emoji short name.</p>
     9    )
    10  }
    11
    12}
    

    保存和关闭文件 在此时,您的浏览器仍然没有发生任何变化,这是因为您尚未使用新组件. 要使用该组件,您需要将其添加到连接到根组件的另一个组件中。

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

    1nano src/App.js
    

    首先,您需要导入组件:

     1[label tutorial-03-component/src/App.js]
     2import React from 'react';
     3
     4import Instructions from './Instructions';
     5
     6import './App.css';
     7
     8...
     9
    10export default App;
    

    因为它是默认导入,你可以导入任何你想要的名称. 最好保持名称一致的可读性 - 导入应该匹配组件名称,这应该匹配文件名称 - 但唯一的固定的规则是,组件必须从一个大写字母开始。 这是React知道它是 一个React组件

    现在您已经导入了组件,可以将其添加到您的代码的其余部分,就像是自定义的 HTML 元素一样:

     1[label tutorial-03-component/src/App.js]
     2import React from 'react';
     3
     4import Instructions from './Instructions.js'
     5
     6...
     7function App() {
     8  const greeting = "greeting";
     9  const displayAction = false;
    10  return(
    11    <div className="container">
    12      <h1 id={greeting}>Hello, World</h1>
    13      {displayAction && <p>I am writing JSX</p>}
    14      <Instructions />
    15      <ul>
    16        {
    17          emojis.map(emoji => (
    18            <li key={emoji.name}>
    19              <button
    20                onClick={displayEmojiName}
    21              >
    22                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
    23              </button>
    24            </li>
    25          ))
    26        }
    27      </ul>
    28    </div>
    29  )
    30}
    31
    32export default App;
    

    在这个代码中,你用角度支架包装了组件. 由于这个组件没有孩子,它可以通过用 /> 结束来自我关闭。

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

    Browser with instruction text

    现在你有文字了,你可以添加一个图像。从 wikimedia下载一个情感动画图像,并用以下命令将其保存到src目录中为emoji.svg:

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

    curl将请求发送到URL,而-o旗允许您将文件保存为src/emoji.svg

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

    1nano src/Instructions.js
    

    导入情感片并通过动态链接将其添加到您的自定义组件中:

     1[label tutorial-03-component/src/Instructions.js]
     2import React, { Component } from 'react';
     3import emoji from './emoji.svg'
     4
     5export default class Instructions extends Component {
     6
     7  render() {
     8    return(
     9      <>
    10        <img alt="laughing crying emoji" src={emoji} />
    11        <p>Click on an emoji to view the emoji short name.</p>
    12      </>
    13    )
    14  }
    15}
    

    请注意,您需要在导入时包括文件扩展 .svg。 导入时,您正在导入由 webpack创建的动态路径。 有关更多信息,请参阅 How To Set Up a React Project with Create React App

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

    当您重新加载时,图像将与其他内容相比非常大:

    Browser window with large emoji image

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

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

     1[label tutorial-03-component/src/Instructions.js]
     2import React, { Component } from 'react';
     3import emoji from './emoji.svg'
     4
     5export default class Instructions extends Component {
     6
     7  render() {
     8    return(
     9      <div className="instructions">
    10        <img alt="laughing crying emoji" src={emoji} />
    11        <p>Click on an emoji to view the emoji short name.</p>
    12      </div>
    13    )
    14  }
    15}
    

    保存并关闭文件 下一步打开App.css:

    1nano src/App.css
    

    创建规则的 .instructions 类选择器:

     1[label tutorial-03-component/src/App.css]
     2.container {
     3    display: flex;
     4    flex-direction: column;
     5    align-items: center;
     6}
     7
     8...
     9
    10.instructions {
    11    display: flex;
    12    flex-direction: column;
    13    align-items: center;
    14}
    

    当你添加一个)。你改变了方向,使一切都垂直与flex-direction: column; 。 行对齐项目:中心;将中心的元素在屏幕上。

    现在你的元素已经排列,你需要更改图像大小. 给div内部的img一个宽度高度100px

     1[label tutorial-03-component/src/App.css]
     2.container {
     3    display: flex;
     4    flex-direction: column;
     5    align-items: center;
     6}
     7
     8...
     9
    10.instructions {
    11    display: flex;
    12    flex-direction: column;
    13    align-items: center;
    14}
    15
    16.instructions img {
    17    width: 100px;
    18    height: 100px;
    19}
    

    保存和关闭文件. 浏览器将重新加载,你会看到图像更小:

    Browser window with smaller image

    此时,您已经创建了一个独立且可重复使用的自定义组件. 若要查看该组件是如何重复使用的,请将第二个实例添加到App.js

    打开App.js:

    1nano src/App.js
    

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

     1[label tutorial-03-component/src/App.js]
     2import React from 'react';
     3
     4import Instructions from './Instructions.js'
     5
     6...
     7
     8function App() {
     9  const greeting = "greeting";
    10  const displayAction = false;
    11  return(
    12    <div className="container">
    13      <h1 id={greeting}>Hello, World</h1>
    14      {displayAction && <p>I am writing JSX</p>}
    15      <Instructions />
    16      <Instructions />
    17      <ul>
    18        {
    19          emojis.map(emoji => (
    20            <li key={emoji.name}>
    21              <button
    22                onClick={displayEmojiName}
    23              >
    24                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
    25              </button>
    26            </li>
    27          ))
    28        }
    29      </ul>
    30    </div>
    31  )
    32}
    33
    34export default App;
    

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

    Browser with two instances of the Instructions component

    在这种情况下,你不想要两个指令的实例,但你可以看到该组件可以高效地重复使用。当你创建自定义按钮或表时,你可能会在一个页面上使用它们多次,这使得它们非常适合自定义组件。

    在文本编辑器中,删除第二个<Instructions />并保存文件:

     1[label tutorial-03-component/src/App.js]
     2import React from 'react';
     3
     4import Instructions from './Instructions.js'
     5
     6...
     7
     8function App() {
     9  const greeting = "greeting";
    10  const displayAction = false;
    11  return(
    12    <div className="container">
    13      <h1 id={greeting}>Hello, World</h1>
    14      {displayAction && <p>I am writing JSX</p>}
    15      <Instructions />
    16      <ul>
    17        {
    18          emojis.map(emoji => (
    19            <li key={emoji.name}>
    20              <button
    21                onClick={displayEmojiName}
    22              >
    23                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
    24              </button>
    25            </li>
    26          ))
    27        }
    28      </ul>
    29    </div>
    30  )
    31}
    32
    33export default App;
    

    现在你有一个可重复使用的独立组件,可以多次添加到母组件中。你现在的结构适用于少数组件,但存在一个小问题. 所有文件都混合在一起. 对于<Instructions>的图像在同一个目录中与<App>>的资产。

    在下一步中,您将创建一个文件结构,通过将其功能,风格和依赖组合在一起,为每个组件提供独立性,从而使您能够根据需要移动它们。

    步骤3 - 创建可读的文件结构

    在此步骤中,您将创建一个文件结构来组织您的组件及其资产,例如图像,CSS,以及其他JavaScript文件. 你会被分组代码 按组件,而不是资产类型。 换句话说,你不会有一个单独的目录,用于CSS,图像,和JavaScript. 相反,你会为每个组件有一个单独的目录,其中包含相关的CSS,JavaScript和图像. 在这两种情况下,你都是分开关切.

    因为你有一个独立的组件,你需要一个文件结构,组合相关的代码. 目前,一切都在同一个目录中. 列出你的src目录中的项目:

    1ls src/
    

    结果将表明事情变得相当混乱:

    1[secondary_label Output]
    2App.css Instructions.js index.js
    3App.js emoji.svg serviceWorker.js
    4App.test.js index.css setupTests.js
    

    您有)坐在您的根组件()和您的自定义组件Instructions.js旁边。

    反应是[故意不可知 (https://reactjs.org/docs/faq-structure.html)关于文件结构. 它不建议特定的结构,项目可以与各种不同的文件等级合作. 但我们建议增加一些顺序,以避免将您的根目录与组件,CSS文件和难以导航的图像一起超载. 另外,明确的命名可以更容易地看清您的项目中哪些部分是相关的. 例如,一个名为Logo.svg'的图像文件不一定是称为header.js'的组件的一部分.

    最简单的结构之一是创建一个组件目录,为每个组件创建一个单独的目录,这将允许您将组件与配置代码分开组,例如服务工作者,同时将资产与组件组合。

    创建一个组件目录

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

    1mkdir src/components
    

    接下来,将以下组件和代码移动到目录中:App.css、App.js、App.test.js、Instructions.js 和emoji.svg:

    1mv src/App.* src/components/
    2mv src/Instructions.js src/components/
    3mv src/emoji.svg src/components/
    

    在这里,您正在使用 wildcard (* )来选择所有开始于 App.的文件。

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

    1[secondary_label Output]
    2Failed to compile.
    3
    4./src/App.js
    5Error: ENOENT: no such file or directory, open 'your_file_path/tutorial-03-component/src/App.js'
    

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

    要做到这一点,打开index.js

    1nano src/index.js
    

    然后更改应用导入路径,从组件/目录导入。

     1[label tutorial-03-component/src/index.js]
     2import React from 'react';
     3import ReactDOM from 'react-dom';
     4import './index.css';
     5import App from './components/App';
     6import * as serviceWorker from './serviceWorker';
     7
     8...
     9
    10serviceWorker.unregister();
    

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

    现在你有组件在一个单独的目录中。随着你的应用程序变得更加复杂,你可能会有API服务、数据存储和实用功能的目录。分离组件代码是第一步,但你仍然在App.css文件中混合了Instructions的CSS代码。

    将组件移动到单个目录

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

    1mkdir src/components/App
    

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

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

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

    1[secondary_label Output]
    2Failed to compile.
    3
    4./src/components/App.js
    5Error: ENOENT: no such file or directory, open 'your_file_path/tutorial-03-component/src/components/App.js'
    

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

    打开 index.js 文件:

    1nano src/index.js
    

    然后更新应用的导入路径,以指向应用目录中的应用组件。

     1[label tutorial-03-component/src/index.js]
     2import React from 'react';
     3import ReactDOM from 'react-dom';
     4import './index.css';
     5import App from './components/App/App';
     6import * as serviceWorker from './serviceWorker';
     7
     8...
     9
    10serviceWorker.unregister();
    

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

    1[secondary_label Output]
    2Failed to compile.
    3
    4./src/components/App/App.js
    5
    6Module not found: Can't resolve './Instructions.js' in 'your_file_path/tutorial-03-component/src/components/App'
    

    由于<Instructions>不是与<App>组件相同的目录级别,您需要更改导入路径。

    1mkdir src/components/Instructions
    

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

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

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

    更新导入路径

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

    打开App.js:

    1nano src/components/App/App.js
    

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

     1[label tutorial-03-component/src/components/App/App.js]
     2import React from 'react';
     3
     4import Instructions from '../Instructions/Instructions.js';
     5
     6import './App.css';
     7
     8...
     9
    10export default App;
    

    现在你的导入都是使用正确的路径,你的浏览器将更新并显示应用程序。

    Browser window with smaller image

    <美元 > [注] 注: 您可以将每个目录中的根文件称为index.js'。 例如,你可以创建src/cups/App/App.js',而不是src/cups/App/index.js'。 好处是你们的进口量少了一点 如果路径指向目录,导入将寻找index.js文件。 在src/index.js'文件中,src/cups/App/index.js'的输入将是import./cups/App'。 这个方法的缺点是,你有很多同名文件,这会使一些文本编辑器难以阅读. 归根结底,这是个人和团队的决定,但最好保持一致. < $ > (美元)

    在共享文件中分离代码

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

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

    1touch src/components/Instructions/Instructions.css
    

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

    1nano src/components/Instructions/Instructions.css
    

    添加您在以前的部分中创建的 CSS 指令:

     1[label tutorial-03-component/src/components/Instructions/Instructions.css]
     2.instructions {
     3    display: flex;
     4    flex-direction: column;
     5    align-items: center;
     6}
     7
     8.instructions img {
     9    width: 100px;
    10    height: 100px;
    11}
    

    然后,从src/components/App/App.css中删除 CSS 指令。

    1nano src/components/App/App.css
    

    删除有关 .instructions 的行. 最终文件将看起来如下:

     1[label tutorial-03-component/src/components/App/App.css]
     2.container {
     3    display: flex;
     4    flex-direction: column;
     5    align-items: center;
     6}
     7
     8button {
     9    font-size: 2em;
    10    border: 0;
    11    padding: 0;
    12    background: none;
    13    cursor: pointer;
    14}
    15
    16ul {
    17    display: flex;
    18    padding: 0;
    19}
    20
    21li {
    22    margin: 0 20px;
    23    list-style: none;
    24    padding: 0;
    25}
    

    最后,在Instructions.js中导入 CSS:

    1nano src/components/Instructions/Instructions.js
    

    使用相对路径导入 CSS:

     1[label tutorial-03-component/src/components/Instructions/Instructions.js]
     2import React, { Component } from 'react';
     3import './Instructions.css';
     4import emoji from './emoji.svg'
     5
     6export default class Instructions extends Component {
     7
     8  render() {
     9    return(
    10      <div className="instructions">
    11        <img alt="laughing crying emoji" src={emoji} />
    12        <p>Click on an emoji to view the emoji short name.</p>
    13      </div>
    14    )
    15  }
    16}
    

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

    Browser window with smaller image

    现在,最后看看结构,首先是‘src/’目录:

    1ls src
    

    您有 root 组件 index.js 和相关的 CSS index.css 以及components/目录和实用文件,如serviceWorker.jssetupTests.js:

    1[secondary_label Output]
    2components serviceWorker.js
    3index.css setupTests.js
    4index.js
    

    接下来,看看内部的组件:

    1ls src/components
    

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

    1[secondary_label Output]
    2App Instructions
    

    如果你查看每个组件的内部,你会看到组件代码、CSS、测试和图像文件,如果它们存在的话。

    1ls src/components/App
    
    1[secondary_label Output]
    2App.css App.js App.test.js
    
    1ls src/components/Instructions
    
    1[secondary_label Output]
    2Instructions.css Instructions.js emoji.svg
    

    在此时,您已经为您的项目创建了一个坚实的结构,您已经移动了大量的代码,但现在您有一个结构,它将更容易扩展。

    有些文件结构可以利用 代码分割来指定一个目录,该目录将被分割为不同的包。 其他文件结构(https://survivejs.com/react/advanced-techniques/structuring-react-projects/# directory-per-view)和使用用于路径的组件的共同目录。

    现在,坚持一个不那么复杂的方法. 随着另一个结构的需求出现,从简单到复杂的转变总是更容易。

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

    步骤4:构建一个功能性组件

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

    功能组件是一个JavaScript函数,返回了一些JSX,不需要扩展任何东西,没有特殊的方法来记忆。

    要将<Instructions>重构为功能组件,您需要将类更改为函数,并删除渲染方法,以便您只留下返回语句。

    要做到这一点,首先在文本编辑器中打开Instructions.js

    1nano src/components/Instructions/Instructions.js
    

    声明更改为功能声明:

     1[label tutorial-03-component/src/components/Instructions/Instructions.js]
     2import React, { Component } from 'react';
     3import './Instructions.css';
     4import emoji from './emoji.svg'
     5
     6export default function Instructions() {
     7  render() {
     8    return(
     9      <div className="instructions">
    10        <img alt="laughing crying emoji" src={emoji} />
    11        <p>Click on an emoji to view the emoji short name.</p>
    12      </div>
    13    )
    14  }
    15}
    

    接下來,移除「{Component }」的輸入:

     1[label tutorial-03-component/src/components/Instructions/Instructions.js]
     2import React from 'react';
     3import './Instructions.css';
     4import emoji from './emoji.svg'
     5
     6export default function Instructions() {
     7
     8  render() {
     9    return(
    10      <div className="instructions">
    11        <img alt="laughing crying emoji" src={emoji} />
    12        <p>Click on an emoji to view the emoji short name.</p>
    13      </div>
    14    )
    15  }
    16}
    

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

     1[label tutorial-03-component/src/components/Instructions/Instructions.js]
     2import React from 'react';
     3import './Instructions.css';
     4import emoji from './emoji.svg'
     5
     6export default function Instructions() {
     7  return(
     8    <div className="instructions">
     9        <img alt="laughing crying emoji" src={emoji} />
    10        <p>Click on an emoji to view the emoji short name.</p>
    11    </div>
    12  )
    13}
    

    保存文件. 浏览器将更新,你会看到你的页面就像以前一样。

    Browser with emoji

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

     1[label tutorial-03-component/src/components/Instructions/Instructions.js]
     2import React from 'react';
     3import './Instructions.css';
     4import emoji from './emoji.svg'
     5
     6const Instructions = () => (
     7  <div className="instructions">
     8    <img alt="laughing crying emoji" src={emoji} />
     9    <p>Click on an emoji to view the emoji short name.</p>
    10  </div>
    11)
    12
    13export default Instructions;
    

    简单的功能组件和基于类的组件非常相似。当你有一个不存储状态的简单组件时,最好使用功能组件。两者之间真正的区别在于你如何存储组件的状态和使用属性。

    结论

    你创建了两个主要的组件类型:功能和类别. 你将组件的部分分为目录,以便你可以将相似的代码组合在一起。

    通过对组件的理解,可以开始将您的应用程序看成可以拆分并重新组合的块. 项目变得模块化和互通. 将整个应用视为一系列组件的能力,是React中思考的一个重要步骤. 如果您想查看更多 React 教程,请查看我们的[React Topic page (https://andsky.com/tags/react), 或者返回 [How To Code in React.js series page (https://www.digitalocean.com/community/tutorial_series/how-to-code-in-react-js).

  • Published At
    Categories with 技术
    comments powered by Disqus