如何在反应中使用 setInterval?
Posted
技术标签:
【中文标题】如何在反应中使用 setInterval?【英文标题】:How to use setInterval in react? 【发布时间】:2020-04-24 13:35:02 【问题描述】:我正在尝试为打字游戏制作一个简单的 setInterval 函数,但它会根据我的语法不断出现故障,或者像现在这样根本没有更新。
如何让它每秒更新一次并调用 if 语句中的函数?
const [counter, setCounter] = useState(10);
useEffect(() =>
let timer = setInterval(() =>
setCounter(counter - 1);
if (counter === 0)
setWordIndex(wordIndex + 1);
setLives(lives - 1);
life.play();
setCounter(10);
, 1000);
, []);
*********编辑***************
这就是我现在所拥有的。第一个答案解决了计数器不递减的异步问题,但我不得不将 if 语句移到 useEffect 之外,以纠正我认为是由同样的问题引起的。
useEffect(() =>
let timer = setInterval(() =>
setCounter( counter => counter - 1);
, 1000);
, []);
if (counter == 0)
setWordIndex(wordIndex + 1);
setLives(lives - 1);
life.play();
setCounter(10);
【问题讨论】:
记得时不时地重新查阅useState 文档。 这能回答你的问题吗? setInterval in a React app 【参考方案1】:在setCounter
函数中使用回调函数。当您在异步函数中调用状态更新时。最好根据之前的状态更新状态。
const [counter, setCounter] = useState(10);
useEffect(() =>
let timer = setInterval(() =>
setCounter(counter =>
const updatedCounter = counter - 1;
if (updatedCounter === 0)
setWordIndex(wordIndex + 1);
setLives(lives - 1);
life.play();
return 10;
return updatedCounter;
); // use callback function to set the state
, 1000);
return () => clearInterval(timer); // cleanup the timer
, []);
【讨论】:
感谢我的计数器现在已完美更新,但是当计数达到 0 时我的 if 语句函数没有触发。有什么想法吗?再次感谢! 想通了!由于同样的异步问题,我不得不将 if 语句移到 useEffect 之外。谢谢! @dnolan 如果将它移到 useEffect 之外,它将刷新两次。这个答案也容易出现内存泄漏。看我的回答。 使用状态更新和内部的逻辑,所以它只会在状态改变时运行。但不要在状态中更新状态。 @Sohail 即使您复制了我的答案,您仍然犯了一个错误。正在修复它...【参考方案2】:之前的答案没有考虑其他状态 - wordIndex 和生活,并且不包括明确的间隔
建议在 setIntervals 中使用回调 setState 并在下次调用 useEffect 时清除间隔
const [counter, setCounter] = React.useState(10);
React.useEffect(() =>
let timer = setInterval(() =>
// It's advisable to use callback setState inside setIntervals
setCounter(prev =>
if (prev !== 0) return prev - 1;
setWordIndex(wordIndex + 1);
setLives(lives - 1);
life.play();
return 10;
);
, 1000);
// And clear the interval next useEffect call
return () => clearInterval(timer);
, [wordIndex, lives]);
【讨论】:
【参考方案3】:之前的答案没有考虑计数器值不会立即更新。由于未清除 setInterval,因此它们也容易发生内存泄漏。
const [counter, setCounter] = useState(10);
useEffect(() =>
let timer = setInterval(() =>
setCounter( counter =>
const nC = counter - 1;
if (nC === 0)
setWordIndex(wordIndex + 1);
setLives(lives - 1);
life.play();
return 10;
return nC;
);
, 1000);
return () => clearInterval(timer);
, []);
【讨论】:
以上是关于如何在反应中使用 setInterval?的主要内容,如果未能解决你的问题,请参考以下文章
不能在反应中使用 setinterval() 附加数组(状态元素)