React <Countdown />: reset time when paused

16 Views Asked by At

I'm in trouble with the component react-countdown. Indeed, I need to play or pause it, depending on whether the state commonStore.chronoIsActive is true or false. It works but the time reset when it paused and I don't know why.

Here is my component:

export const GameTimer = () => {
    const { classes } = useStyles();
    const commonStore = useCommonStore();
    const startDate = useRef(Date.now());
    const chrono = commonStore.chronoValue ? commonStore.chronoValue * 1000 : 0;
    const timeRef = useRef<Countdown>(null);

    //affichage du chrono
    const renderTime = ({ minutes, seconds }: IRenderTime) => {
        //utilisé padStart pour toujours avoir 2 chiffres pas défaut
        const paddedMinutes = String(minutes).padStart(2, '0');
        const paddedSeconds = String(seconds).padStart(2, '0');

        return (
            <span
                className={classes.time}
            >{`${paddedMinutes}:${paddedSeconds}`}</span>
        );
    };

    const onCompletedTime = () => {
        commonStore.setChronoIsActive(false);
        socket.emit('data', { action: 'endChrono' });
    };

    useEffect(() => {
        if (commonStore.chronoIsActive) {
            timeRef.current?.start();
        } else {
            timeRef.current?.pause();
        }
    }, [commonStore.chronoIsActive]);

    return (
        <Countdown
            ref={timeRef}
            date={startDate.current + chrono}
            renderer={renderTime}
            autoStart={commonStore.chronoIsActive}
            onComplete={onCompletedTime}
        />
    );
};

I tried differents things:

  • put a key on the component which doesn't change to prevent reset
  • try to use useRef() as you can see
  • try to put Date.now() directly in date prop of Countdown instead of startDate.current
  • try to memoize my component like this:
const Timer = () => {
    const { classes } = useStyles();
    const commonStore = useCommonStore();
    const startDate = useRef(Date.now());
    const chrono = commonStore.chronoValue ? commonStore.chronoValue * 1000 : 0;
    const timeRef = useRef<Countdown>(null);

    //affichage du chrono
    const renderTime = ({ minutes, seconds }: IRenderTime) => {
        //utilisé padStart pour toujours avoir 2 chiffres pas défaut
        const paddedMinutes = String(minutes).padStart(2, '0');
        const paddedSeconds = String(seconds).padStart(2, '0');

        return (
            <span
                className={classes.time}
            >{`${paddedMinutes}:${paddedSeconds}`}</span>
        );
    };

    const onCompletedTime = () => {
        commonStore.setChronoIsActive(false);
        socket.emit('data', { action: 'endChrono' });
    };

    useEffect(() => {
        if (commonStore.chronoIsActive) {
            timeRef.current?.start();
        } else {
            timeRef.current?.pause();
        }
    }, [commonStore.chronoIsActive]);

    return (
        <Countdown
            ref={timeRef}
            date={Date.now() + chrono}
            renderer={renderTime}
            autoStart={commonStore.chronoIsActive}
            onComplete={onCompletedTime}
        />
    );
};

export const GameTimer = memo(Timer);

I checked the api document and I also checked questions already on stack overflow but I didn't find the answer.

I don't know what to do now although I think there is a simple thing I missed...

I would really appreciate some help

Thanks a lot

0

There are 0 best solutions below