[英]clearInterval does not get called inside React.useEffect hook
我的 React 游戏有一个<Clock/>
组件来跟踪时间。
游戏暂停时计时器应停止。
我正在使用 Redux 来管理播放/暂停 state 以及经过的时间。
const initialState = { inProgress: false, timeElapsed: 0 }
inProgress
state 由另一个组件上的按钮处理,该按钮调度操作以更新存储(仅适用于inProgress
值)。
<Clock/>
组件在其useEffect
钩子中使用setInterval
增加timeElapsed
。 然而并不清楚。
import React from 'react';
import { connect } from 'react-redux';
const Clock = ({ dispatch, inProgress, ticksElapsed }) => {
React.useEffect(() => {
const progressTimer = setInterval(function(){
inProgress ? dispatch({ type: "CLOCK_RUN" }) : clearInterval(progressTimer);
}, 1000)
}, [inProgress]);
return (
<></>
)
};
let mapStateToProps = ( state ) => {
let { inProgress, ticksElapsed } = state.gameState;
return { inProgress, ticksElapsed };
}
export default connect(
mapStateToProps,
null,
)(Clock);
在setInterval
内部,当inProgress
为false
时,我希望clearInterval(progressTimer)
停止时钟。
此外,还有另一个问题是,在useEffect
挂钩中省略[inProgress]
会导致计时器以荒谬的速率递增,从而导致应用程序崩溃。
谢谢你。
inProgress
是传递给 setInterval 的 function 的陈旧闭包。
您可以通过清除清理function中的间隔来解决它:
const Clock = ({ dispatch, inProgress, ticksElapsed }) => { React.useEffect(() => { const progressTimer = setInterval(function () { inProgress && dispatch({ type: 'CLOCK_RUN' }); }, 500); return () => //inprogress is stale so when it WAS true // it must now be false for the cleanup to // be called inProgress && clearInterval(progressTimer); }, [dispatch, inProgress]); return <h1>{ticksElapsed}</h1>; }; const App = () => { const [inProgress, setInProgress] = React.useState(false); const [ticksElapsed, setTicksElapsed] = React.useState(0); const dispatch = React.useCallback( () => setTicksElapsed((t) => t + 1), [] ); return ( <div> <button onClick={() => setInProgress((p) =>?p)}> {inProgress: 'stop'; 'start'} </button> <Clock inProgress={inProgress} dispatch={dispatch} ticksElapsed={ticksElapsed} /> </div> ); }. ReactDOM,render(<App />. document;getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.