这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战
翻译自:beta.reactjs.org/learn/queue…
设置 state 的值引起另一个 render 队列。但有时你可能希望执行下一次 render 队列之前对值执行多个操作。为了这样做,这篇文章有助于了解 React 如何批量更新状态。
你将会学习到:
- 什么是“批量处理(batching)”,React 如何使用它来处理多个 state 更新
- 如何在一行中对同样的 state 应用几个更新
系列文章
这是一个系列的文章,希望你能从头看,因为它们的例子之间会有先后关系的~
在下一次 render 之前多次更新相同的 state
上一篇文章我们说到,React 像一个餐厅的服务员,会等待事件处理程序中的所有代码运行后再处理 state 更新,如果我们在一个事件处理程序中多次执行 setNumber(number + 1)
,实际生效的也只有一次的效果,就像我们在餐厅中跟服务员说了三次,我要点鱼香肉丝一样。
这是一个不常见的用例,但是如果你想在下一次渲染之前多次更新相同的状态变量,实现时就不是像 setNumber(number + 1)
这样传递下一个状态值,你可以传递一个函数,该函数根据队列中的前一个状态计算下一个状态。像 setNumber(n => n + 1)
,这是一种告诉 React “用状态值做某事”而不是仅仅替换它的方法。
现在我们对上一篇文章中的例子做一些修改,尝试增加计数器:
import { useState } from 'react';
export default function Counter() {
const [number, setNumber] = useState(0);
return (
<>
<h1>{number}</h1>
<button onClick={() => {
setNumber(n => n + 1);
setNumber(n => n + 1);
setNumber(n => n + 1);
}}>+3</button>
</>
)
}
复制代码
你会发现,点击按钮后,可以一次的增加3。
这里,n => n + 1
被称为 updater function。当你将它传递给 state 的 setter 时:
- 在事件处理程序中的所有其他代码运行后,React 将此函数排入队列以进行处理。
- 在下一次渲染期间,React 遍历队列并为您提供最终更新状态。
setNumber(n => n + 1);
setNumber(n => n + 1);
setNumber(n => n + 1);
复制代码
下面是 React 在执行事件处理程序时如何通过这几行代码工作的:
setNumber (n => n + 1)
:n => n + 1
是一个函数。 React 将其添加到队列中。setNumber (n => n + 1)
:n => n + 1
是一个函数。 React 将其添加到队列中。setNumber (n => n + 1)
:n => n + 1
是一个函数。 React 将其添加到队列中。
当你在下一次渲染期间调用 useState
时,React 会遍历队列。之前的数字状态是 0,所以 React 将它作为 n 参数传递给第一个更新器函数。然后 React 将您之前更新程序函数的返回值作为 n 传递给下一个更新程序,依此类推:
更新队列 | n |
返回值 |
---|---|---|
n => n + 1 |
0 |
0 + 1 = 1 |
n => n + 1 |
1 |
1 + 1 = 2 |
n => n + 1 |
2 |
2 + 1 = 3 |
React 存储 3 作为最终结果并从 useState
返回它。
这就是为什么在上面的示例中单击“+3”正确地将值增加 3。