描述 UI

React 是一个用于渲染用户界面 (UI) 的 JavaScript 库。UI 由按钮、文本和图像等小型单元构建。React 允许你将它们组合成可重复使用的、嵌套的组件。从网站到手机应用程序,屏幕上的所有内容都可以分解为组件。在本节中,你将学习如何创建、自定义和有条件地显示 React 组件。

你的第一个组件

React 应用程序由称为组件的 UI 的独立部分构建。React 组件是一个 JavaScript 函数,你可以用标记来装饰它。组件可以像按钮一样小,也可以像整个页面一样大。这是一个渲染三个Profile组件的 Gallery 组件

function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

准备好学习这个主题了吗?

阅读 你的第一个组件 学习如何声明和使用 React 组件。

阅读更多

导入和导出组件

你可以在一个文件中声明多个组件,但是大型文件可能会难以导航。为了解决这个问题,你可以将组件导出到它自己的文件中,然后从另一个文件中导入该组件

import Profile from './Profile.js';

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

准备好学习这个主题了吗?

阅读 导入和导出组件 学习如何将组件拆分为它们自己的文件。

阅读更多

使用 JSX 编写标记

每个 React 组件都是一个 JavaScript 函数,它可能包含一些 React 渲染到浏览器中的标记。React 组件使用称为 JSX 的语法扩展来表示该标记。JSX 看起来很像 HTML,但它更严格,可以显示动态信息。

如果我们将现有的 HTML 标记粘贴到 React 组件中,它并不总是能正常工作

export default function TodoList() {
  return (
    // This doesn't quite work!
    <h1>Hedy Lamarr's Todos</h1>
    <img
      src="https://i.imgur.com/yXOvdOSs.jpg"
      alt="Hedy Lamarr"
      class="photo"
    >
    <ul>
      <li>Invent new traffic lights
      <li>Rehearse a movie scene
      <li>Improve spectrum technology
    </ul>

如果你有像这样的现有 HTML,你可以使用转换器 来修复它

export default function TodoList() {
  return (
    <>
      <h1>Hedy Lamarr's Todos</h1>
      <img
        src="https://i.imgur.com/yXOvdOSs.jpg"
        alt="Hedy Lamarr"
        className="photo"
      />
      <ul>
        <li>Invent new traffic lights</li>
        <li>Rehearse a movie scene</li>
        <li>Improve spectrum technology</li>
      </ul>
    </>
  );
}

准备好学习这个主题了吗?

阅读 使用 JSX 编写标记 学习如何编写有效的 JSX。

阅读更多

使用大括号在 JSX 中使用 JavaScript

JSX 允许你在 JavaScript 文件中编写类似 HTML 的标记,将渲染逻辑和内容保持在同一位置。有时,你可能想要在该标记中添加一些 JavaScript 逻辑或引用动态属性。在这种情况下,你可以在你的 JSX 中使用大括号来“打开一个窗口”到 JavaScript 中

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}

准备好学习这个主题了吗?

阅读 使用大括号在 JSX 中使用 JavaScript 学习如何从 JSX 访问 JavaScript 数据。

阅读更多

将 Props 传递给组件

React 组件使用Props 来相互通信。每个父组件都可以通过给子组件提供 Props 来向它们传递一些信息。Props 可能让你想起 HTML 属性,但是你可以通过它们传递任何 JavaScript 值,包括对象、数组、函数,甚至 JSX!

import { getImageUrl } from './utils.js'

export default function Profile() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}

function Avatar({ person, size }) {
  return (
    <img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={size}
      height={size}
    />
  );
}

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

准备好学习这个主题了吗?

阅读 将 Props 传递给组件 以了解如何传递和读取 props。

阅读更多

条件渲染

您的组件通常需要根据不同的条件显示不同的内容。在 React 中,您可以使用 JavaScript 语法(如 if 语句、&&? : 运算符)有条件地渲染 JSX。

在此示例中,JavaScript && 运算符用于有条件地渲染复选标记。

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✔'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}

准备好学习这个主题了吗?

阅读 条件渲染 以了解有条件地渲染内容的不同方法。

阅读更多

渲染列表

您经常希望从数据集合中显示多个相似的组件。您可以使用 JavaScript 的 filter()map() 与 React 一起过滤和转换您的数据数组,使其成为组件数组。

对于每个数组项,您需要指定一个 key。通常,您希望使用来自数据库的 ID 作为 key。键让 React 即使列表发生变化,也能跟踪每个项目的列表位置。

import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const listItems = people.map(person =>
    <li key={person.id}>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        known for {person.accomplishment}
      </p>
    </li>
  );
  return (
    <article>
      <h1>Scientists</h1>
      <ul>{listItems}</ul>
    </article>
  );
}

准备好学习这个主题了吗?

阅读 渲染列表 以了解如何渲染组件列表以及如何选择键。

阅读更多

保持组件纯粹

某些 JavaScript 函数是纯粹的。纯函数

  • 专注于自身。它不会更改任何在调用它之前存在的对象或变量。
  • 相同的输入,相同的输出。对于相同的输入,纯函数应该始终返回相同的结果。

通过严格地只将您的组件编写为纯函数,您可以避免随着代码库的增长而出现一大类令人费解的错误和不可预测的行为。以下是一个不纯组件的示例

let guest = 0;

function Cup() {
  // Bad: changing a preexisting variable!
  guest = guest + 1;
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup />
      <Cup />
      <Cup />
    </>
  );
}

您可以通过传递道具而不是修改预先存在的变量来使此组件变为纯组件

function Cup({ guest }) {
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup guest={1} />
      <Cup guest={2} />
      <Cup guest={3} />
    </>
  );
}

准备好学习这个主题了吗?

阅读 保持组件纯粹 以了解如何将组件编写为纯的、可预测的函数。

阅读更多

您的 UI 作为树

React 使用树来模拟组件和模块之间的关系。

React 渲染树是组件之间父子关系的表示。

A tree graph with five nodes, with each node representing a component. The root node is located at the top the tree graph and is labelled 'Root Component'. It has two arrows extending down to two nodes labelled 'Component A' and 'Component C'. Each of the arrows is labelled with 'renders'. 'Component A' has a single 'renders' arrow to a node labelled 'Component B'. 'Component C' has a single 'renders' arrow to a node labelled 'Component D'.
A tree graph with five nodes, with each node representing a component. The root node is located at the top the tree graph and is labelled 'Root Component'. It has two arrows extending down to two nodes labelled 'Component A' and 'Component C'. Each of the arrows is labelled with 'renders'. 'Component A' has a single 'renders' arrow to a node labelled 'Component B'. 'Component C' has a single 'renders' arrow to a node labelled 'Component D'.

一个 React 渲染树示例。

靠近树顶部的组件,靠近根组件,被认为是顶级组件。没有子组件的组件是叶子组件。这种组件分类有助于理解数据流和渲染性能。

模拟 JavaScript 模块之间的关系是理解您的应用程序的另一种有用方式。我们将其称为模块依赖树。

A tree graph with five nodes. Each node represents a JavaScript module. The top-most node is labelled 'RootModule.js'. It has three arrows extending to the nodes: 'ModuleA.js', 'ModuleB.js', and 'ModuleC.js'. Each arrow is labelled as 'imports'. 'ModuleC.js' node has a single 'imports' arrow that points to a node labelled 'ModuleD.js'.
A tree graph with five nodes. Each node represents a JavaScript module. The top-most node is labelled 'RootModule.js'. It has three arrows extending to the nodes: 'ModuleA.js', 'ModuleB.js', and 'ModuleC.js'. Each arrow is labelled as 'imports'. 'ModuleC.js' node has a single 'imports' arrow that points to a node labelled 'ModuleD.js'.

一个模块依赖树示例。

依赖树通常由构建工具用来捆绑客户端下载和渲染所需的所有相关 JavaScript 代码。较大的捆绑包大小会导致 React 应用程序的用户体验下降。理解模块依赖树有助于调试此类问题。

准备好学习这个主题了吗?

阅读 您的 UI 作为树 以了解如何为 React 应用程序创建渲染和模块依赖树,以及它们如何成为提高用户体验和性能的有用思维模型。

阅读更多

下一步是什么?

前往 您的第一个组件 开始逐页阅读本章内容!

或者,如果您已经熟悉这些主题,为什么不阅读关于 添加交互性 的内容?