添加交互性
屏幕上的某些内容会随着用户输入而更新。例如,点击图片库会切换活动图片。在 React 中,随时间变化的数据被称为状态。 你可以为任何组件添加状态,并根据需要更新它。在本章中,你将学习如何编写处理交互、更新状态并随时间显示不同输出的组件。
响应事件
React 允许你向 JSX 添加事件处理函数。 事件处理函数是你自己的函数,它们会在用户交互(如点击、悬停、聚焦表单输入等)时被触发。
像 <button>这样的内置组件仅支持内置的浏览器事件,如onClick。然而,你也可以创建自己的组件,并为其事件处理函数属性指定任何你喜欢的、与应用相关的名称。
状态:组件的记忆
组件通常需要根据交互来改变屏幕上显示的内容。在表单中输入应更新输入字段,点击图片轮播的“下一个”应更改显示的图片,点击“购买”会将商品放入购物车。组件需要“记住”一些东西:当前的输入值、当前的图片、购物车。在 React 中,这种特定于组件的记忆被称为 状态。
你可以使用 useStateHook 为组件添加状态。Hook是一种特殊的函数,它能让你的组件使用 React 的功能(状态就是这些功能之一)。useStateHook 允许你声明一个状态变量。它接收初始状态并返回一对值:当前状态和一个让你更新它的状态设置函数。
以下是一个图片库如何使用和更新点击状态的示例:
渲染与提交
在你的组件显示在屏幕上之前,它们必须由 React 进行渲染。理解这个过程里的步骤将帮助你思考你的代码是如何执行的,并解释其行为。
想象一下,你的组件是厨房里的厨师,用食材组装美味的菜肴。在这个场景中,React 是服务员,负责接收顾客的订单并将其送达。这个请求和提供 UI 的过程包含三个步骤:
- 触发一次渲染(将食客的订单送到厨房)
- 渲染组件(在厨房准备订单)
- 提交到 DOM(将订单放到桌上)
触发
渲染
提交
插图作者:Rachel Lee Nabors
状态如同快照
与普通的 JavaScript 变量不同,React 状态的行为更像一个快照。设置它并不会改变你已经拥有的状态变量,而是会触发一次重新渲染。起初这可能会令人惊讶!
这种行为有助于你避免一些难以察觉的错误。这里有一个小聊天应用。试着猜猜如果你先按下“发送”,然后再将收件人改为 Bob,会发生什么。五秒后alert中会显示谁的名字?
排队进行一系列状态更新
这个组件有缺陷:点击“+3”只会增加一次分数。
状态如同快照解释了为什么会发生这种情况。设置状态会请求一次新的重新渲染,但不会改变正在运行的代码中的状态。所以在你调用score 之后,0 仍然是 setScore(score + 1)。
你可以通过传递一个更新器函数来设置状态以修复此问题。注意,将setScore(score + 1)替换为setScore(s => s + 1)即可修复“+3”按钮。这允许你将多个状态更新加入队列。
更新状态中的对象
状态可以保存任何类型的 JavaScript 值,包括对象。但是你不应该直接更改存储在 React 状态中的对象和数组。相反,当你想要更新一个对象或数组时,你需要创建一个新的(或复制一个现有的),然后将状态更新为使用该副本。
通常,你会使用...展开语法来复制你想要更改的对象和数组。例如,更新一个嵌套对象可能如下所示:
如果在代码中复制对象变得繁琐,你可以使用像Immer这样的库来减少重复代码:
更新状态中的数组
数组是另一种可以存储在状态中的可变 JavaScript 对象,应将其视为只读。就像处理对象一样,当你想要更新存储在状态中的数组时,你需要创建一个新数组(或复制现有数组),然后将状态设置为使用新数组:
如果在代码中复制数组变得繁琐,你可以使用像Immer这样的库来减少重复代码:
接下来是什么?
前往 响应事件 开始逐页阅读本章!
或者,如果你已经熟悉这些主题,为什么不阅读一下管理状态呢?
