v19.2Latest

快速入门

欢迎阅读 React 文档!本页将向你介绍日常开发中会使用到的 80% 的 React 概念。

您将学习
  • 如何创建和嵌套组件
  • 如何添加标记和样式
  • 如何显示数据
  • 如何渲染条件和列表
  • 如何响应事件并更新屏幕
  • 如何在组件之间共享数据

创建和嵌套组件

React 应用由组件构成。组件是用户界面(UI)的一部分,拥有自己的逻辑和外观。组件可以小到一个按钮,也可以大到整个页面。

React 组件是返回标记的 JavaScript 函数:

声明了MyButton后,你可以将其嵌套到另一个组件中:

注意<MyButton />以大写字母开头。这就是你识别 React 组件的方式。React 组件名称必须以大写字母开头,而 HTML 标签必须小写。

看看结果:

export default关键字指定了文件中的主要组件。如果你对某些 JavaScript 语法不熟悉,MDNjavascript.info提供了很好的参考资料。

使用 JSX 编写标记

上面看到的标记语法被称为JSX。它是可选的,但大多数 React 项目因其便利性而使用 JSX。所有我们推荐的本地开发工具都开箱即用地支持 JSX。

JSX 比 HTML 更严格。你必须闭合标签,例如<br />。你的组件也不能返回多个 JSX 标签。你必须将它们包装到一个共享的父级中,例如<div>...</div>或一个空的<>...</>包装器:

如果你有大量 HTML 需要转换为 JSX,可以使用在线转换器

添加样式

在 React 中,你使用className指定 CSS 类。它的工作方式与 HTML 的class属性相同:

然后在单独的 CSS 文件中为其编写 CSS 规则:

React 没有规定如何添加 CSS 文件。最简单的情况下,你会在 HTML 中添加一个<link>标签。如果你使用构建工具或框架,请查阅其文档以了解如何向项目添加 CSS 文件。

显示数据

JSX 允许你将标记放入 JavaScript 中。花括号让你可以“转义回”JavaScript,以便嵌入代码中的某些变量并将其显示给用户。例如,这将显示user.name

你也可以从 JSX 属性中“转义到 JavaScript”,但必须使用花括号而不是引号。例如,className="avatar"将字符串"avatar"作为 CSS 类传递,而src={user.imageUrl}读取 JavaScript 变量user.imageUrl的值,然后将该值作为src属性传递:

你也可以在 JSX 花括号内放置更复杂的表达式,例如,字符串拼接

在上面的例子中,style={{}}并不是特殊语法,而是一个放在{} 内的普通 style={ }JSX 花括号内的对象。当你的样式依赖于 JavaScript 变量时,可以使用style 属性。

条件渲染

在 React 中,没有特殊的语法来编写条件。相反,你将使用与编写常规 JavaScript 代码时相同的技术。例如,你可以使用if语句来有条件地包含 JSX:

如果你更喜欢简洁的代码,可以使用条件 ? 运算符。if不同,它可以在 JSX 内部使用:

当你不需要 else分支时,也可以使用更短的逻辑 && 语法

所有这些方法也适用于有条件地指定属性。如果你对其中一些 JavaScript 语法不熟悉,可以先始终使用if...else

渲染列表

你将依赖 JavaScript 特性,如for 循环数组 map() 函数 来渲染组件列表。

例如,假设你有一个产品数组:

在你的组件内部,使用map() 函数将产品数组转换为 <li>项数组:

请注意 <li>有一个key属性。对于列表中的每个项目,你应该传递一个字符串或数字,该字符串或数字在其同级项中唯一标识该项目。通常,键应来自你的数据,例如数据库 ID。React 使用你的键来了解如果你稍后插入、删除或重新排序项目时发生了什么。

响应事件

你可以通过在组件内声明事件处理函数来响应事件:

请注意 onClick={handleClick} 末尾没有括号!不要调用事件处理函数:你只需要传递它。当用户点击按钮时,React 会调用你的事件处理函数。

更新屏幕

通常,你会希望你的组件“记住”一些信息并显示它。例如,你可能想计算按钮被点击的次数。为此,请向你的组件添加状态

从 React 导入useState

现在你可以在组件内部声明一个状态变量

你会从useState得到两样东西:当前的状态(count),以及一个可以更新它的函数(setCount)。你可以给它们起任何名字,但惯例是写成[something, setSomething]

按钮首次显示时,count将为0,因为你向useState()传递了0。当你想改变状态时,调用setCount()并向其传递新值。点击此按钮将增加计数器:

React 将再次调用你的组件函数。这次,count将为1。接着会是2。依此类推。

如果你多次渲染同一个组件,每个组件都会拥有自己的状态。请分别点击每个按钮:

请注意每个按钮如何“记住”自己的count状态,并且不影响其他按钮。

使用 Hook

use开头的函数被称为HookuseState是 React 提供的内置 Hook。你可以在API 参考中找到其他内置 Hook。你也可以通过组合现有的 Hook 来编写自己的 Hook。

Hook 比其他函数限制更严格。你只能在组件(或其他 Hook)的顶层调用 Hook。如果你想在条件语句或循环中使用useState,请提取一个新组件并将其放在那里。

在组件间共享数据

在前面的例子中,每个MyButton都有自己独立的count,并且当每个按钮被点击时,只有被点击按钮的count会改变:

展示三个组件树的图表,一个父组件标记为 MyApp,两个子组件标记为 MyButton。两个 MyButton 组件都包含一个值为零的 count。展示三个组件树的图表,一个父组件标记为 MyApp,两个子组件标记为 MyButton。两个 MyButton 组件都包含一个值为零的 count。

最初,每个MyButtoncount状态都是0

与上一张相同的图表,第一个子组件 MyButton 的 count 被高亮显示,表示点击后其值增加到一。第二个 MyButton 组件仍包含值零。与上一张相同的图表,第一个子组件 MyButton 的 count 被高亮显示,表示点击后其值增加到一。第二个 MyButton 组件仍包含值零。

第一个MyButton将其count更新为1

然而,通常你会需要组件共享数据并始终保持同步更新

为了让两个MyButton组件显示相同的count并一起更新,你需要将状态从各个按钮“向上”移动到包含它们所有的最接近的组件中。

在这个例子中,这个组件是MyApp

展示三个组件树的图表,一个父组件标记为MyApp,两个子组件标记为MyButton。MyApp包含一个值为零的count状态,该值被传递给两个MyButton组件,这两个组件也显示值为零。展示三个组件树的图表,一个父组件标记为MyApp,两个子组件标记为MyButton。MyApp包含一个值为零的count状态,该值被传递给两个MyButton组件,这两个组件也显示值为零。

最初,MyAppcount状态是0,并被传递给两个子组件。

与上一张相同的图表,父组件MyApp的count值高亮显示,表示点击后值递增为一。流向两个子组件MyButton的路径也高亮显示,每个子组件中的count值都设置为一,表示值已向下传递。与上一张相同的图表,父组件MyApp的count值高亮显示,表示点击后值递增为一。流向两个子组件MyButton的路径也高亮显示,每个子组件中的count值都设置为一,表示值已向下传递。

点击时,MyApp将其count状态更新为1并传递给两个子组件。

现在,当你点击任一按钮时,MyApp中的count会改变,这将改变MyButton中的两个计数值。以下是如何在代码中表达这一点。

首先,将状态向上移动,从MyButton移到MyApp中:

然后,将状态向下传递,从MyApp传递给每个MyButton,同时传递共享的点击处理函数。你可以使用JSX花括号向MyButton传递信息,就像之前对<img>这样的内置标签所做的那样:

像这样向下传递的信息称为props。现在,MyApp组件包含count状态和handleClick事件处理函数,并将两者都作为props向下传递给每个按钮。

最后,修改MyButton读取从其父组件传递过来的props:

当你点击按钮时,onClick处理函数被触发。每个按钮的onClickprop被设置为MyApp内部的handleClick函数,因此其中的代码会运行。该代码调用setCount(count + 1),使count状态变量递增。新的count值作为prop传递给每个按钮,因此它们都显示新值。这被称为“状态提升”。通过将状态向上移动,你已在组件之间共享了它。

下一步

至此,你已经了解了编写React代码的基础知识!

查看教程,将这些知识付诸实践,并用React构建你的第一个迷你应用。