组件通常需要根据交互更改屏幕上显示的内容。输入表单应该更新输入字段,单击轮播图上的“下一个”应该更改显示的图片,单击“购买”应该将商品放入购物车。组件需要“记住”某些东西:当前输入值、当前图片、购物车。在
React 中,这种组件特有的记忆被称为state
。
- 局部变量无法在多次渲染中持久保存。 当 React 再次渲染这个组件时,它会从头开始渲染——不会考虑之前对局部变量的任何更改。
- 更改局部变量不会触发渲染。 React 没有意识到它需要使用新数据再次渲染组件。
要使用新数据更新组件,需要做两件事:
- 保留 渲染之间的数据。
- 触发 React 使用新数据渲染组件(重新渲染)。
useState Hook 提供了这两个功能:
- State 变量 用于保存渲染间的数据。
- State setter 函数 更新变量并触发 React 再次渲染组件
添加一个state变量
要添加 state 变量,先从文件顶部的 React 中导入 useState:
这里的 [ 和 ] 语法称为数组解构,它允许你从数组中读取值。 useState 返回的数组总是正好有两项。
import { useState } from 'react';
const [index, setIndex] = useState(0);
执行流程:
- 组件进行第一次渲染。 因为你将 0 作为 index 的初始值传递给 useState,它将返回 [0, setIndex]。 React 记住 0 是最新的 state 值。
- 你更新了 state。当用户点击按钮时,它会调用 setIndex(index + 1)。 index 是 0,所以它是 setIndex(1)。这告诉 React 现在记住 index 是 1 并触发下一次渲染。
- 组件进行第二次渲染。React 仍然看到 useState(0),但是因为 React 记住 了你将 index 设置为了 1,它将返回 [1, setIndex]。
- 以此类推
Hooks ——以 use 开头的函数——只能在组件或自定义 Hook 的最顶层调用。 你不能在条件语句、循环语句或其他嵌套函数内调用 Hook。Hook 是函数,但将它们视为关于组件需求的无条件声明会很有帮助。在组件顶部 “use” React 特性,类似于在文件顶部“导入”模块。
-
当一个组件需要在多次渲染间“记住”某些信息时使用 state 变量。
-
State 变量是通过调用
useState Hook
来声明的。 -
Hook 是以
use
开头的特殊函数。它们能让你 “hook” 到像 state 这样的 React 特性中。 -
Hook 可能会让你想起 import:它们需要在非条件语句中调用。调用 Hook 时,包括
useState
,仅在组件或另一个 Hook的顶层被调用才有效。 -
useState Hook
返回一对值:当前 state 和更新它的函数。 -
你可以拥有多个 state 变量。在内部,React 按顺序匹配它们。
-
State 是组件私有的。如果你在两个地方渲染它,则每个副本都有独属于自己的 state。
⚠️State 变量仅用于在组件重渲染时保存信息。在单个事件处理函数中,普通变量就足够了。当普通变量运行良好时,不要引入 state 变量。
以下是一个使用了普通变量 name 的固定版本,这个变量声明于需要它的函数中。
export default function FeedbackForm() {
function handleClick() {
const name = prompt('What is your name?');
alert(`Hello, ${name}!`);
}
return (
<button onClick={handleClick}>
Greet
</button>
);
}