在setTimeout回调函数中更新React数组状态


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])

相关内容

  • 没有找到相关文章

最新更新