如何使用 JSX 创建 React 元素

作者选择了 Creative Commons以作为 Write for Donations计划的一部分获得捐赠。

介绍

在本教程中,您将学习如何用 JSX 描述元素。JSX 是一个抽象,允许您在您的 JavaScript代码中编写类似于 HTML 的语法,并允许您构建类似标准 HTML 标记的 React 组件。

由于 JSX 允许您在标记中写 JavaScript,您将能够利用 JavaScript 函数和方法,包括 array 地图和 https://andsky.com/tech/tutorials/how-to-write-conditional-statements-in-javascript 的短路评估。

作为教程的一部分,您会直接在标出时在按钮上捕获点击事件,并在语法与标准的HTML不完全匹配时捕获实例,比如CSS类. 在这个教程结尾,你会有一个工作应用程序,使用各种JSX特性来显示一个具有内置点击听器的元素列表. 这是React应用程序中常见的模式,您在学习框架的过程中会经常使用. 还可以将标准的HTML元素与JavaScript相混合,看React如何赋予您创建小而可再用代码的能力.

前提条件

步骤 1 – 将标记添加到一个 React 元素

正如前面提到的,React有一个名为JSX的特殊标记语言,它是HTML和JavaScript语法的组合,看起来像这样:

1<div>
2  {inventory.filter(item => item.available).map(item => (
3    <Card>
4        <div className="title"}>{item.name}</div>
5        <div className="price">{item.price}</div>
6    </Card>
7    ))
8  }
9</div>

您将识别一些JavaScript功能,如 .filter.map,以及一些标准的HTML,如

这是JSX,该特殊标记语言使React组件具有HTML的感觉,具有JavaScript的力量。

在此步骤中,您将学习如何将基本的HTML类似语法添加到现有的React元素中。 首先,您将添加标准的HTML元素到JavaScript函数中,然后在浏览器中查看编译的代码。

在命令行上,运行以下脚本以使用create-react-app安装新项目:

1npx create-react-app jsx-tutorial

项目完成后,更改到目录:

1cd jsx-tutorial

在新的终端卡或窗口中,使用 Create React App start script启动项目。

1npm start

如果该项目没有在浏览器窗口中打开,您可以找到它在 http://localhost:3000/。 如果您正在从远程服务器运行,则地址将是 http://your_IP_address:3000

您的浏览器将加载 React 应用程序,作为 Create React 应用程序的一部分。

React template project

您将构建一组全新的自定义组件,因此您需要从清除一些锅炉板代码开始,以便您可以有一个空的项目。 在文本编辑器中开始打开 App.js

在新终端中,移动到项目文件夹并使用以下命令打开src/App.js:

1nano src/App.js

你會看到這樣的檔案:

 1[label jsx-tutorial/src/App.js]
 2import React from 'react';
 3import logo from './logo.svg';
 4import './App.css';
 5
 6function App() {
 7  return (
 8    <div className="App">
 9      <header className="App-header">
10        <img src={logo} className="App-logo" alt="logo" />
11        <p>
12          Edit <code>src/App.js</code> and save to reload.
13        </p>
14        <a
15          className="App-link"
16          href="https://reactjs.org"
17          target="_blank"
18          rel="noopener noreferrer"
19        >
20          Learn React
21        </a>
22      </header>
23    </div>
24  );
25}
26
27export default App;

现在,删除./logo.svg导入徽标的行和函数中返回陈述后的一切。 更改为返回null`。

1[label jsx-tutorial/src/App.js]
2import React from 'react';
3import './App.css';
4
5function App() {
6  return null;
7}
8
9export default App;

保存和退出文本编辑器。

最后,删除标志,在终端窗口中键入以下命令:

1rm src/logo.svg

您将不会在应用程序中使用此 SVG 文件,并且您应该在工作时删除未使用的文件。

现在,您已删除项目的这些部分,您可以继续探索JSX的各个方面。这个标记语言由React编译,最终成为您在网页上看到的HTML。

这意味着你可以写出看起来像HTML的内容,并期望渲染的HTML将是相似的。

首先,如果您查看运行您的服务器的标签或窗口,您将看到以下内容:

1[secondary_label Output]
2...
3./src/App.js
4  Line 1:8:  'React' is defined but never used no-unused-vars
5...

這是 linter告訴你,你不使用已輸入的 React 代碼. 当你添加到你的代碼的行 `import React from'react' 时,你正在輸入 JavaScript 代碼,將 JSX 轉換為 React 代碼。

让我们通过添加少量的JSX来改变这一点,开始用一个Hello, World的例子来代替null:

1[label jsx-tutorial/src/App.js]
2import React from 'react';
3import './App.css';
4
5function App() {
6  return <h1>Hello, World</h1>;
7}
8
9export default App;

保存文件. 如果您查看终端与服务器运行,警告消息将消失. 如果您访问您的浏览器,您将看到消息作为一个h1元素。

browser screen showing "Hello, World"

接下来,在<h1>标签下,添加一个包含我正在写JSX字符串的段落标签。

 1[label jsx-tutorial/src/App.js]
 2import React from 'react';
 3import './App.css';
 4
 5function App() {
 6  return(
 7    <h1>Hello, World</h1>
 8    <p>I am writing JSX</p>
 9  )
10}
11
12export default App;

由于 JSX 涵盖多个行,您将需要将表达式包装成栏。

当您这样做时,您将在运行您的服务器的终端中看到一个错误:

 1[secondary_label Output]
 2./src/App.js
 3  Line 7:5:  Parsing error: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?
 4
 5   5 |   return(
 6   6 |     <h1>Hello, World</h1>
 7>  7 |     <p>I am writing JSX</p>
 8     |     ^
 9   8 |   )
10   9 | }
11  10 |

当您从函数或语句中返回 JSX 时,您必须返回单个元素。

修复是一个小小的代码更改。用一个 空标签环绕代码。一个空标签是没有任何单词的HTML元素。

在您的编辑器中回到 ./src/App.js 并添加空标签:

 1[label jsx-tutorial/src/App.js]
 2import React from 'react';
 3import './App.css';
 4
 5function App() {
 6  return(
 7    <>
 8      <h1>Hello, World</h1>
 9      <p>I am writing JSX</p>
10    </>
11  )
12}
13
14export default App;

空标签创建一个单个元素,但当编译代码时,它不会被添加到最终标记中。

<$>[注] 注: 您还可以用div代替空标签包装代码,只要代码返回一个元素。

保存代码并离开文件. 您的浏览器将更新并显示更新的页面与段落元素. 此外,当代码被转换时,空标签被删除:

Browser showing markup and devtools showing markup without empty tags

您现在已将一些基本的 JSX 添加到您的组件中,并了解如何将所有 JSX 嵌入到一个组件中。

步骤 2 — 添加具有属性元素的样式

在此步骤中,您将对组件中的元素进行格式化,以了解HTML属性如何与JSX一起工作。在React中有许多(https://reactjs.org/docs/faq-styling.html)的格式化选项。其中一些涉及写CSS在JavaScript中,其他使用预处理器。在本教程中,您将使用进口的CSS和CSS类。

现在你有了你的代码,是时候添加一些风格了。在文本编辑器中打开App.css:

1nano src/App.css

由于您正在使用新的 JSX,当前的 CSS 是指不再存在的元素,因为您不需要 CSS,您可以删除它。

删除代码后,你将有一个空的文件。

接下来,您将添加一些风格来中心文本. 在src/App.css中,添加以下代码:

1[label jsx-tutorial/src/App.css]
2.container {
3    display: flex;
4    flex-direction: column;
5    align-items: center;
6}

在此代码块中,您创建了一个名为 .containerCSS 类选择器,并使用它来使用 display: flex来中心内容。

保存文件并退出. 浏览器将更新,但不会发生任何变化. 在您看到更改之前,您需要将 CSS 类添加到您的 React 组件中。

1nano src/App.js

CSS 代码已经被导入了导入 / App.css的行,这意味着 webpack将拖入代码以创建最终的风格表,但要将 CSS 应用到您的元素,您需要添加类。

首先,在文本编辑器中,将空标签<>更改为<div>

 1[label jsx-tutorial/src/App.js]
 2import React from 'react';
 3import './App.css';
 4
 5function App() {
 6  return(
 7    <div>
 8      <h1>Hello, World</h1>
 9      <p>I am writing JSX</p>
10    </div>
11  )
12}
13
14export default App;

在这个代码中,你用div代替了空标签,空标签有助于组合你的代码而不添加任何额外的标签,但在这里你需要使用一个div,因为空标签不接受任何HTML属性(https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes)。

接下来,你需要添加类的名称,这就是JSX将开始偏离HTML的地方,如果你想添加一个类到一个常见的HTML元素,你会这样做:

1<div class="container">

但是,由于JSX是JavaScript,它有一些局限性,其中一个局限性是JavaScript有(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar# Keywords)。这意味着你不能在任何JavaScript代码中使用某些单词,例如,你不能创建一个名为null的变量,因为这个单词已经保留了。

其中一个保留的单词是class。React通过稍微改变这个保留的单词来解决问题。而不是添加属性class,你会添加属性className。通常,如果属性不像预期的那样工作,请尝试添加骆驼案例版本。另一个略有不同的属性是你会用来标签的属性for

<$>[note] 注: 在React中,属性通常被称为 props。特性是您可以传递给其他自定义组件的数据片段。它们看起来像属性一样,但它们不匹配任何HTML规格。在本教程中,我们将称它们为属性,因为它们主要被用作标准HTML属性。这将使它们与不像HTML属性行为的特性区分开来,这些属性将在本系列后面被涵盖。

现在你已经知道 React 中的属性是如何使用的,你可以更新你的代码以包括风格. 在文本编辑器中,将className="container``添加到你打开的div`标签:

 1[label jsx-tutorial/src/App.js]
 2import React from 'react';
 3import './App.css';
 4
 5function App() {
 6  return(
 7    <div className="container">
 8      <h1>Hello, World</h1>
 9      <p>I am writing JSX</p>
10    </div>
11  )
12}
13
14export default App;

保存文件. 当您这样做时,页面将重新加载,内容将集中。

Centered html elements in a browser.

className属性在React中是独一无二的,你可以将大多数HTML属性添加到JSX中,而不会有任何变化,例如,回到你的文本编辑器,并将一个ID添加到你的<h1>元素中。

 1[label jsx-tutorial/src/App.js]
 2import React from 'react';
 3import './App.css';
 4
 5function App() {
 6  return(
 7    <div className="container">
 8      <h1 id="greeting">Hello, World</h1>
 9      <p>I am writing JSX</p>
10    </div>
11  )
12}
13
14export default App;

保存页面并重新加载浏览器. 它将是相同的。

到目前为止,JSX看起来像标准标记,但JSX的优点是,虽然它看起来像HTML,但它具有JavaScript的力量,这意味着你可以分配变量并将它们引用到你的属性中。

在文本编辑器中,添加以下突出的行来引用属性:

 1[label jsx-tutorial/src/App.js]
 2import React from 'react';
 3import './App.css';
 4
 5function App() {
 6  const greeting = "greeting";
 7  return(
 8    <div className="container">
 9     <h1 id={greeting}>Hello, World</h1>
10      <p>I am writing JSX</p>
11    </div>
12  )
13}
14
15export default App;

在此代码中,您在返回声明上方创建了一个变量,名为问候,其值为问候,然后将变量引用到您的<h1>标签的id属性中。

保存和退出文件. 页面将是相同的,但具有id标签。

Page with id tag highlighted in the developer tools

到目前为止,您已经自行处理了几个元素,但您也可以使用 JSX 添加许多 HTML 元素,并将它们嵌入到创建复杂的页面中。

为了证明这一点,你将创建一个页面,列出一个情感片的列表. 这些情感片将被一个<按钮>元素包裹。 当你点击情感片时,你会得到他们的 CLDR 简称

要开始,您需要在页面中添加一些更多元素。在文本编辑器中打开src/App.js

1nano src/App.js

首先,通过添加以下突出的行来添加一个情感片列表:

 1[label jsx-tutorial/src/App.js]
 2import React from 'react';
 3import './App.css';
 4
 5function App() {
 6  const greeting = "greeting";
 7  return(
 8    <div className="container">
 9      <h1 id={greeting}>Hello, World</h1>
10      <p>I am writing JSX</p>
11      <ul>
12        <li>
13            <button>
14              <span role="img" aria-label="grinning face" id="grinning face">😀</span>
15            </button>
16        </li>
17        <li>
18          <button>
19              <span role="img" aria-label="party popper" id="party popper">🎉</span>
20          </button>
21        </li>
22        <li>
23          <button>
24              <span role="img" aria-label="woman dancing" id="woman dancing">💃</span>
25          </button>
26        </li>
27      </ul>
28    </div>
29  )
30}
31
32export default App;

在这里,你创建了一个<ul>标签,以保持情感符列表.每个情感符位于一个单独的<li>元素中,并被一个<按钮>元素包围。

您还用一个<span>标签包围了情感符号,其中有几种属性。每个span都有role(https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Role_Img)属性,设置为img角色。这将向可访问性软件发出信号,该元素是像图像一样(https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Role_Img)。此外,每个span>也有一个aria-label(https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute)和一个id属性,包含了情感符号的名称。

当您以这种方式编写代码时,您正在使用 语义元素,这将有助于让页面易于访问和易于对屏幕读者进行分析。

保存和退出文件. 您的浏览器将更新,您将看到以下内容:

browser with emoji as a list

现在添加一点风格,打开文本编辑器中的CSS代码:

1nano src/App.css

添加以下突出代码以删除按钮的默认背景和边界,同时增加字体大小:

 1[label jsx-tutorial/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}

在此代码中,您使用了字体大小,边界和其他参数来调整按钮的外观并更改字体,您还删除了列表风格,并将显示:倾斜添加到<ul>元素中,使其横向。

保存并关闭 CSS 文件. 您的浏览器将更新,您将看到以下内容:

list with default styles removed

您现在已经使用了几种 JSX 元素,这些元素看起来像常规的 HTML。您已经添加了类、ID 和 aria 标签,并使用了数据作为字符串和变量,但 React 还使用属性来定义元素应该如何响应用户事件。

步骤 3 – 将事件添加到元素

在此步骤中,您将使用特殊属性将事件添加到元素中,并捕获按钮元素上的点击事件,您将学习如何从事件中捕获信息,以发送另一个操作或使用文件范围中的其他信息。

现在你有一个基本的信息页面,现在是时候添加一些事件了,有很多事件处理器(https://andsky.com/tech/tutorials/understanding-events-in-javascript# event-handlers-and-event-listeners),你可以添加到HTML元素。React给你访问所有这些。

首先,添加 onclick 事件处理器。这允许您将一些JavaScript代码直接添加到您的元素中,而不是添加一个事件聆听器:

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

由于这是 JSX,所以你 camelCased onclick,这意味着你添加了它作为 onClick. 这个 onClick 属性使用一个 匿名函数来获取有关被点击的项目的信息。

您已添加一个匿名的 箭头函数,该函数将从点击的按钮获取事件,该事件将有一个目标,即<span>元素。

在您的浏览器中,点击一个情感符号,你会得到一个警告,名称。

Alert for party popper

您可以通过声明函数一次并将其传递给每个onClick操作来减少重复性,因为该函数不依赖于输入和输出以外的任何东西,您可以声明其在主组件函数之外。

在文本编辑器中,创建一个名为displayEmojiName的函数,该函数将事件收集并用一个id 调用alert()函数,然后将函数传递给每个onClick属性:

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

在您的浏览器中,点击一个情感符号,你会看到相同的警告。

在此步骤中,您将事件添加到每个元素中,您还看到 JSX 如何使用元素事件的略有不同的名称,并开始写可重复使用的代码,通过使用该函数并在多个元素上重复使用它。

步骤 4 – 绘制数据以创建元素

在此步骤中,您将超越使用JSX作为简单的标记,您将学习将其与JavaScript相结合,以创建动态标记,从而减少代码并提高可读性。

JSX不局限于一个类似HTML的语法,它还为您提供了直接在标记中使用JavaScript的能力,您已经通过将函数转移到属性来尝试过这点,您还使用了变量来重复使用数据,现在是时候使用标准JavaScript代码直接从数据中创建JSX了。

在您的文本编辑器中,您需要在src/App.js文件中创建一组情感符号数据. 如果您关闭了该文件,则重新打开该文件:

1nano src/App.js

添加一个包含有emojiemoji名称的对象(https://andsky.com/tech/tutorials/understanding-objects-in-javascript)的数组。 请注意,emoji 需要被引用符号包围。

 1[label jsx-tutorial/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: "grinning face"
10  },
11  {
12    emoji: "🎉",
13    name: "party popper"
14  },
15  {
16    emoji: "💃",
17    name: "woman dancing"
18  }
19];
20
21function App() {
22...
23}
24
25export default App;

要在 JSX 中使用 JavaScript,您需要用弯曲的字符串包围它: {}. 这与您在属性中添加函数时相同。

要创建 React 组件,您需要将数据转换为 JSX 元素。 要做到这一点,您将对数据进行地图并返回 JSX 元素。

首先,一组项目需要被一个容器<div>包围。 其次,每个项目需要一个名为钥匙的特殊属性。 钥匙需要是一个独特的数据,React可以使用它来跟踪元素,以便它知道何时更新组件(https://reactjs.org/docs/lists-and-keys.html# keys)。

以下是简化示例,将名称列表绘制成包含<div>的名称:

 1...
 2const names = [
 3    "Atul Gawande",
 4    "Stan Sakai",
 5    "Barry Lopez"
 6];
 7
 8return(
 9    <div>
10        {names.map(name => <div key={name}>{name}</div>)}
11    </div>
12)
13...

结果的HTML将看起来像这样:

1...
2<div>
3    <div>Atul Gawande</div>
4    <div>Stan Sakai</div>
5    <div>Barry Lopez</div>
6</div>
7...

转换的情绪符列表将是相似的。<ul>将是容器。你将对数据进行地图并返回一个<li>带有情绪符的短名称的密钥。你将用循环的信息代替<button><span>标签中的硬编码数据。

在您的文本编辑器中,添加以下内容:

 1[label jsx-tutorial/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  return(
24    <div className="container">
25      <h1 id={greeting}>Hello, World</h1>
26      <p>I am writing JSX</p>
27      <ul>
28        {
29          emojis.map(emoji => (
30            <li key={emoji.name}>
31              <button
32                onClick={displayEmojiName}
33              >
34                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
35              </button>
36            </li>
37          ))
38        }
39      </ul>
40    </div>
41  )
42}
43
44export default App;

在代码中,你 mapped<ul>标签中的emojis阵列上返回了<li>字符,在每个<li>字符中,你使用了emoji名称作为key字符,按钮将具有与正常相同的功能,在<span>元素中,用name代替aria-labelid

保存文件. 您的窗口将更新,您将看到数据. 请注意,密钥不在生成的HTML中。

Browser with developer tools showing updated HTML without key props

将 JSX 与标准的 JavaScript 相结合,可以为您提供大量的工具来动态创建内容,您可以使用您想要的任何标准的 JavaScript. 在此步骤中,您将硬编码的 JSX 替换成一个数组和循环来动态创建 HTML。

步骤 5 – 条件显示短电路元素

在此步骤中,您将使用短路来条件显示某些HTML元素,这将允许您创建可基于额外信息隐藏或显示HTML的组件,从而让您的组件能够灵活处理多个情况。

例如,您可能只希望向用户显示警告消息,如果某些情况是真实的,或者您可能希望向管理员显示一些用户帐户信息,而您不希望正常用户看到。

要做到这一点,你将使用 短圈。这意味着你将使用一个条件,如果第一个部分是真实的,它将返回第二部分的信息。

如果您只想显示一个按钮,如果用户已登录,则将元素包围成弯曲的轴承,并在之前添加条件。

1{isLoggedIn && <button>Log Out</button>}

在本示例中,您正在使用&&运算符,该运算符将返回最后一个值,如果一切都是真实的。否则,它将返回false,该运算符将告诉 React 不要返回任何额外的标记。

要尝试这个,添加以下突出的行:

 1[label jsx-tutorial/src/App.js]
 2import React from 'react';
 3import './App.css';
 4
 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      <ul>
15...
16      </ul>
17    </div>
18  )
19}
20
21export default App;

在您的文本编辑器中,您创建了一个名为displayAction的变量,其值为false。然后您将<p>标签包围成弯曲的夹克,在弯曲的夹克开始时,您添加了displayAction &&,以创建条件。

保存文件,你会看到元素在你的浏览器中消失. 至关重要的是,它也不会出现在生成的HTML中。

Browser with developer tools showing no paragraph element

此时displayAction的值是硬编码的,但您也可以将该值存储为 状态或将其从 家长组件传输为插件。

在此步骤中,您学会了如何条件显示元素,这使您能够根据其他信息创建可自定义的组件。

结论

在这一点上,您已经创建了一个自定义应用程序,使用 JSX. 您已经学会了如何将类似 HTML 元素添加到您的组件中,将样式添加到这些元素中,传递属性来创建语义和可访问标记,并将事件添加到组件中。

使用JavaScript和HTML的组合,您可以构建动态组件,这些组件是灵活的,并允许您的应用程序增长和变化。

如果您想了解更多关于 React 的信息,请查看我们的 React 主题页面

Published At
Categories with 技术
comments powered by Disqus