我正在尝试在组件(例如Home here)在视图中渲染时创建一个自动计数器。计数器应从1开始并在10处停止。但是我无法在10处清除setInterval。计数器仍在递增。问题是什么?
非常感谢。
export const Home = () => {
const [counter, setCounter] = useState(1)
let timer = useRef()
const animate = () => {
if(counter === 10){
clearInterval(timer.current)
}else{
setCounter((previous) => previous + 1)
}
}
useEffect(() => {
timer.current = window.setInterval(() => {
animate()
}, 900)
}, [])
return (
<div style={{textAlign: "center"}}>
<h1>{counter}</h1>
</div>
)
}
问题是animate
在的初始值上关闭了函数counter
,即1。因此,条件counter === 10
永远不会评估为真。
这就是为什么您永远不应该对useEffect
钩子的依赖项撒谎。这样做可能会导致错误,因为关闭了先前组件渲染中的陈旧值。
您可以摆脱animate()
功能,并在useEffect
挂钩内编写逻辑。
function App() {
const [counter, setCounter] = React.useState(1);
const counterRef = React.useRef(counter);
React.useEffect(() => {
const id = setInterval(() => {
// if "counter" is 10, stop the interval
if (counterRef.current === 10) {
clearInterval(id);
} else {
// update the "counter" and "counterRef"
setCounter((prevCounter) => {
counterRef.current = ++prevCounter;
return prevCounter;
});
}
}, 900);
// clearn interval on unmount
return () => clearInterval(id);
}, []);
return (
<div style={{ textAlign: "center" }}>
<h1>{counter}</h1>
</div>
);
}
ReactDOM.render(<App/>, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句