function Painter({tempArr}) {
const [arr, setArr] = useState([]);
useEffect(() => {
tempArr.map((item, index) => {
setTimeout(() => {
setArr([...arr, item]);
}, 2000 * index)
})
}, [tempArr])
我检查了状态arr
在数组中只有一个元素。我期望arr
状态在最后一次超时后将具有tempArr
数组的所有元素。但是每次重新渲染都只有新的元素。
我发现使用updater函数可以解决这个问题。
function Painter({tempArr}) {
const [arr, setArr] = useState([]);
useEffect(() => {
tempArr.map((item), index => {
setTimeout(() => {
setArr(prev => [...prev, item]); // using the updater function
}, 2000 * index)
})
}, [tempArr])
但是我不知道为什么这个可以,而上面那个不行。
我不知道为什么这个可以,而上面那个不行。
setArr([...arr, item]);
此代码中的arr
是效果运行时arr
的值。所以假设这是第一次渲染,arr
是一个空数组。您设置了几个超时,每个超时都会复制空数组并添加一个项。它们不复制最近的数组,总是原始数组。
因此,第一个计时器将复制一个空数组并添加第一项。然后第二个计时器复制空数组并添加第二项。第一个项不在这个数组中,因为第二个超时不知道该项。这样继续下去,每次超时都会覆盖前一个超时所做的工作,只有最后一个setState会持续存在。
setArr(prev => [...prev, item]);
当你切换到这个版本时,你现在正在复制数组的最新版本。因此,第一个超时复制空数组并添加一个项。然后第二个数组复制只有一个元素的数组,并添加第二个元素。以此类推,每次构建数组。
您需要在超时时间中设置增量时间。您可以将常量时间与索引相乘来执行此操作。
useEffect(() => {
tempArr.map((item, index) => {
setTimeout(() => {
setArr([...arr, item]);
}, 2000 * index)
})
}, [tempArr])