簡體   English   中英

clearInterval 不會在 React.useEffect 鈎子中被調用

[英]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內部,當inProgressfalse時,我希望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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM