[英]clearInterval not working in React functional component
I am using setInterval
and clearInterval
in a React functional component.我在 React 功能组件中使用
setInterval
和clearInterval
。 I am incrementing the count inside the setInterval
and want to clearInterval
once it has reached certain value.but it is not clearing out, not sure what I am doing wrong.我正在增加
setInterval
内的计数,并希望在达到某个值后清除clearInterval
。但它没有清除,不确定我做错了什么。
const { useState, useEffect } = React; /*export default*/ function App() { const [chartsCount, setChartsCount] = useState(1); useEffect(() => { const chartsCountId = setInterval(() => { setChartsCount((count) => { console.log('set chart count function is running ', { chartsCount }); if (chartsCount >= 3/*16*/) { console.log('We have reached the limit'); clearInterval(chartsCountId); } return count + 1; }); }, 1000); return () => { clearInterval(chartsCountId); }; }, [chartsCount]); return ( <div> <h1>Hello StackBlitz!</h1> <p>Start editing to see some magic happen :)</p> </div> ); } const root = ReactDOM.createRoot(document.getElementById("root")); root.render(<App />);
<div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
You should handle the logic outside the setState, since you are including the count
in the deps of the effect you don't need to read the fresh state in a callback:您应该处理 setState 之外的逻辑,因为您在效果的 deps 中包含
count
,您不需要在回调中读取新状态:
const { useState, useEffect } = React; /*export default*/ function App() { const [chartsCount, setChartsCount] = useState(1); useEffect(() => { const chartsCountId = setInterval(() => { if (chartsCount >= 3 /*16*/ ) { // *** console.log('We have reached the limit'); clearInterval(chartsCountId); } else { setChartsCount(c => c + 1); console.log("Current count: ", chartsCount ) } }, 1000); return () => { clearInterval(chartsCountId); }; }, [chartsCount]); // *** return ( <div> <h1>Hello StackBlitz!</h1> <p>Start editing to see some magic happen :)</p> </div> ); } const root = ReactDOM.createRoot(document.getElementById("root")); root.render(<App />);
<div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
Or if you want just a simple and quick fix to your code:或者,如果您只想简单快速地修复您的代码:
setChartsCount((count) => {
console.log('set chart count function is running ', { chartsCount });
if (chartsCount >= 3/*16*/) {
console.log('We have reached the limit');
clearInterval(chartsCountId);
return count
}
return count + 1;
});
Basically you are setting the same count if you reach the limit, and that will prevent the effect from running again.基本上,如果达到限制,您将设置相同的计数,这将阻止效果再次运行。
The problem is that you've made chartsCount
a dependency on the useEffect
, so every time it changes one interval is canceled and another is started.问题是您已经使
chartsCount
成为 useEffect 的依赖useEffect
,因此每次更改时都会取消一个间隔并启动另一个间隔。 That includes when the count has gone above the limit, since you're still adding to the count in that case.这包括当计数超过限制时,因为在这种情况下您仍在增加计数。
Instead:反而:
chartsCount
a dependency of the effect, andchartsCount
成为效果的依赖项,并且count
(the parameter if your setChartsCount
callback) rather than chartsCount
in your effect codecount
(如果您的setChartsCount
回调的参数)而不是chartsCount
Updated snippet, see the four comments with ***
:更新的代码片段,请参阅带有
***
的四个评论:
const { useState, useEffect } = React; /*export default*/ function App() { const [chartsCount, setChartsCount] = useState(1); useEffect(() => { const chartsCountId = setInterval(() => { setChartsCount((count) => { console.log('set chart count function is running ', { chartsCount: count }); // *** if (count >= 3/*16*/) { // *** console.log('We have reached the limit'); clearInterval(chartsCountId); return count; // *** >>IF<< you don't want count incremented the last time } return count + 1; }); }, 1000); return () => { clearInterval(chartsCountId); }; }, []); // *** return ( <div> <h1>Hello StackBlitz!</h1> <p>Start editing to see some magic happen :)</p> </div> ); } const root = ReactDOM.createRoot(document.getElementById("root")); root.render(<App />);
<div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.