React Page Not Updating with SetInterval [solved]

React Page Not Updating with SetInterval [solved]
0

I am working on the Pomodoro Clock project (using React). I have been trying to use setInterval as the timer. When I attempt to run the timer, the display only updates once. The callback in setInterval is running like it is supposed to, every second. However, the page doesn’t update to reflect that. Any idea what is causing that? Thanks for your help!

Here is the function calling setInterval

const startStop = () => {
        console.log("calling startStop");
        if(timerActiveFlag) {
            console.log("timerActiveFlag is true...");
            setTimerActiveFlag(false);
        } else {
            console.log("timerActiveFlag is false...");
            setTimerActiveFlag(true);
            interval = setInterval(
                () => {
                    console.log("SetInterval function running...");
                    setSessionMilliseconds(sessionMilliseconds - 1000);
                }, 1000);
        }
    };

Here is the useEffect that should run:

    useEffect(
        () => {
            console.log("Updating display");
            if(sessionActiveFlag) {
                setDisplay(millisecondsToTimeString(sessionMilliseconds));
            } else {
                setDisplay(millisecondsToTimeString(restMilliseconds));    
            }
        }, [sessionActiveFlag, sessionMilliseconds, restMilliseconds]
    );

Edit (more code):

Here are all of my state variables, effects, and the return for the component (App).

    const [sessionActiveFlag, setSessionActiveFlag] = useState(true);
    const [session, setSession] = useState(25);
    const [rest, setRest] = useState(5);
    const [sessionMilliseconds, setSessionMilliseconds] = useState(minToMilli(session));
    const [restMilliseconds, setRestMilliseconds] = useState(minToMilli(rest));
    const [display, setDisplay] = useState(millisecondsToTimeString(sessionMilliseconds));
    const [timerActiveFlag, setTimerActiveFlag] = useState(false);


    useEffect(
        () => {
            setSessionMilliseconds(minToMilli(session));
            setRestMilliseconds(minToMilli(rest));
        }, [session, rest]
    );

    useEffect(
        () => {
            console.log("Updating display");
            if(sessionActiveFlag) {
                setDisplay(millisecondsToTimeString(sessionMilliseconds));
            } else {
                setDisplay(millisecondsToTimeString(restMilliseconds));    
            }
        }, [sessionActiveFlag, sessionMilliseconds, restMilliseconds]
    );

    const startStop = () => {
        console.log("calling startStop");
        if(timerActiveFlag) {
            console.log("timerActiveFlag is true...");
            setTimerActiveFlag(false);
        } else {
            console.log("timerActiveFlag is false...");
            setTimerActiveFlag(true);
            interval = setInterval(
                () => {
                    console.log("SetInterval function running...");
                    setSessionMilliseconds(sessionMilliseconds - 1000);
                }, 1000);
        }
    };



    return (
        <div className="clock-container">
            <h1 id="title">Pomodoro Clock</h1>
            <div className="settings">
                <UserSetTime 
                    title="Break Length"
                    labelId="break-label"
                    iconIdDec="break-decrement"
                    iconIdInc="break-increment"
                    lengthId="break-length"
                    timeLength={rest}
                    increment={incrementRest}
                    decrement={decrementRest}
                />
                <UserSetTime
                    title="Session Length"
                    labelId="session-label"
                    iconIdDec="session-decrement"
                    iconIdInc="session-increment"
                    lengthId="session-length"
                    timeLength={session}
                    increment={incrementSession}
                    decrement={decrementSession}
                />
            </div>
            <Timer display={display} sessionActive={sessionActiveFlag}/>
            <Controls reset={reset} startStop={startStop} />
        </div>
    );
};

Can you post more of your code? For instance I’d like to see the scope of sessionActiveFlag, and timerActiveFlag. And how are you calling startStop? Can’t discern much from the snippet you posted.

I edited my post with some more code. I pass startStop as a prop to another component. The two flags are state variables within App.

Edit: It looks like the state is never changing within setInterval. Why would that be the case?

I can’t test it, but my initial assumption is that your startStop function is inside your react function, so it gets recreated every time the component renders. Therefore you can’t access previous state there. Look at this github issue for guidance, and if it still doesn’t work after that, let me know and we’ll take another stab at it

1 Like

Late reply, but thank you very much! This was the exact issue.