clearInterval 在 React 功能组件中不起作用
clearInterval not working in React functional component
我在 React 功能组件中使用 setInterval
和 clearInterval
。我正在增加 setInterval
内的计数,并希望 clearInterval
一旦它达到某个值 value.but 它不会清除,不确定我做错了什么。
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>
问题是您已经使 chartsCount
成为 useEffect
的依赖项,因此每次它发生变化时,都会取消一个间隔并启动另一个间隔。当计数超过限制时,包括,因为在这种情况下您仍在添加计数。
改为:
- 不要让
chartsCount
成为效果的依赖项,并且
- 在效果代码中使用
count
(setChartsCount
回调的参数)而不是 chartsCount
已更新代码段,查看带有 ***
的四个评论:
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>
您应该在 setState 之外处理逻辑,因为您将 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>
或者如果您只想简单快速地修复您的代码:
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;
});
基本上,如果达到限制,您将设置相同的计数,这将防止效果再次 运行。
我在 React 功能组件中使用 setInterval
和 clearInterval
。我正在增加 setInterval
内的计数,并希望 clearInterval
一旦它达到某个值 value.but 它不会清除,不确定我做错了什么。
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>
问题是您已经使 chartsCount
成为 useEffect
的依赖项,因此每次它发生变化时,都会取消一个间隔并启动另一个间隔。当计数超过限制时,包括,因为在这种情况下您仍在添加计数。
改为:
- 不要让
chartsCount
成为效果的依赖项,并且 - 在效果代码中使用
count
(setChartsCount
回调的参数)而不是chartsCount
已更新代码段,查看带有 ***
的四个评论:
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>
您应该在 setState 之外处理逻辑,因为您将 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>
或者如果您只想简单快速地修复您的代码:
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;
});
基本上,如果达到限制,您将设置相同的计数,这将防止效果再次 运行。