tl;dr:你应该使用功能更新 https://reactjs.org/docs/hooks-reference.html#functional-updates syntax.
这实际上更多的是关于理解 JavaScript 闭包而不是钩子。为了演示发生了什么,这里有一些基于您的代码increment
方法,但没有任何钩子——只是简单的 JavaScript。
async function increment() {
const arr = [];
let nextArr = undefined;
nextArr = [...arr, 'a'];
await pause()
nextArr = [...arr, 'b'];
await pause()
nextArr = [...arr, 'c'];
await pause()
nextArr = [...arr, 'd'];
await pause()
nextArr = [...arr, 'e'];
await pause()
}
在此函数结束时,您期望的值是多少nextArr
to be? ['a', 'b', 'c', 'd', 'e']
or ['e']
(提示:您已经在应用程序中看到了结果)
nextArr
代表您传递给状态设置器的内容。
作为旁注,我建议您使用以下命名约定setArr
而不是useArr
设置器变量名称。useX
应该为自定义钩子保留——不用于状态设置器。
您想要做的事情类似于以下内容:
async function increment() {
const arr = [];
let nextArr = undefined;
nextArr = [...arr, 'a'];
await pause()
nextArr = [...nextArr, 'b'];
await pause()
nextArr = [...nextArr, 'c'];
await pause()
nextArr = [...nextArr, 'd'];
await pause()
nextArr = [...nextArr, 'e'];
await pause()
}
此代码利用前一个值来创建下一个值。这功能更新 https://reactjs.org/docs/hooks-reference.html#functional-updates可以使用语法来达到这种效果。通过我建议的功能更新语法和命名更改,您的increment
函数看起来像这样:
async function increment() {
setArr(prevArr => [...prevArr, 'a'])
await pause()
setArr(prevArr => [...prevArr, 'b'])
await pause()
setArr(prevArr => [...prevArr, 'c'])
await pause()
setArr(prevArr => [...prevArr, 'd'])
await pause()
setArr(prevArr => [...prevArr, 'e'])
await pause()
}