英文:
setting state in nested setTimeouts bug
问题
I'm trying to add JSX elements to a state array on a timer. So once the component is rendered, after 1200ms, a JSX element should be added to the array. 2 Seconds later, another JSX element should be added to the array.
The issue is, once the second setBlocks
is called, the first JSX Element gets removed. Wondering if there is a way around this, or a better way to pull this off. Here is the useEffect
:
useEffect(() => {
setTimeout(() => {
setBlocks([...blocks, serverBlock]);
setTimeout(() => {
setBlocks([...blocks, commandBlock]);
}, 2000);
}, 1200);
}, []);
And here is how I'm rendering the elements:
<div>{blocks.map((block) => block)}</div>
英文:
I'm trying to add JSX elements to a state array on a timer. So once the component is rendered, after 1200ms, a JSX element should be added to the array. 2 Seconds later, another JSX element should be added to the array.
The issue is, once the second setBlocks
is called, the first JSX Element gets removed. Wondering if there is a way around this, or a better way to pull this off. Here is the useEffect
:
useEffect(() => {
setTimeout(() => {
setBlocks([...blocks, serverBlock]);
setTimeout(() => {
setBlocks([...blocks, commandBlock]);
}, 2000);
}, 1200);
}, []);
And here is how I'm rendering the elements:
<div>{blocks.map((block) => block)}</div>
答案1
得分: 1
你应该传递一个更新函数给 setBlocks
,以便根据实际的先前值更改状态。
还需要从 useEffect
返回一个清理函数,以在组件卸载时取消超时。
useEffect(() => {
const id = setTimeout(() => {
setBlocks(prevBlocks => [...prevBlocks, serverBlock]);
setTimeout(() => {
setBlocks(prevBlocks => [...prevBlocks, commandBlock]);
}, 2000);
}, 1200);
return () => clearTimeout(id);
}, []);
英文:
You should pass an updater function to setBlocks
so you can change the state based on the actual previous value.
You also need to return a cleanup function from useEffect
to cancel the timeout when the component is unmounted.
useEffect(() => {
const id = setTimeout(() => {
setBlocks(prevBlocks => [...prevBlocks, serverBlock]);
setTimeout(() => {
setBlocks(prevBlocks => [...prevBlocks, commandBlock]);
}, 2000);
}, 1200);
return () => clearTimeout(id);
}, []);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论