Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

restart Function not working as Expected #70

Open
prpercival opened this issue Oct 25, 2021 · 11 comments
Open

restart Function not working as Expected #70

prpercival opened this issue Oct 25, 2021 · 11 comments

Comments

@prpercival
Copy link

If I call restart after the timer has already expired, the timer updates to the new Date but it doesn't start counting down.

Simple Example:

const [hasTimeExpired, setHasTimeExpired] = useState(false);

let dt = new Date();

const {
    seconds,
    minutes,
    hours,
    days,
    isRunning,
    start,
    pause,
    resume,
    restart,
} = useTimer({ expiryTimestamp: dt, onExpire: () => setHasTimeExpired(true), autoStart: false });

useEffect(() => {
    let dt = new Date();

    dt.setSeconds(dt.getSeconds() + 15);

    restart(dt, true);
}, [])

useEffect(() => {
    let dt = new Date();
    dt.setSeconds(dt.getSeconds() + 120);

    restart(dt, true);
}, [hasTimeExpired])

return (
    <div className= "Clock-Wrapper">
        <span className="Clock-Time-Front">
            {hours}:{minutes}:{seconds}
        </span>
    </div>
)
@erikcvisser
Copy link

Hi @prpercival, did you make any progress with this? I have the same issue and want to restart the timer after it has expired.

Interestingly, the 'restart' button in the official demo site does reset+start the 10 minute timer after first expiry. Also, the onExpire does not seem to be doing anything strange.

@prpercival
Copy link
Author

prpercival commented Dec 1, 2021

@erikcvisser After playing around with it, I found that the timer will only restart if you re-render the component your timer is in when updating the time. Not an ideal solution, but it enabled me to reset the timer.

@sjwen98
Copy link

sjwen98 commented Dec 3, 2021

use setTimeout()

setTimeout(() => {
restart((new Date().setSeconds(new Date().getSeconds() + 50)));
}, 1000)

@erikcvisser
Copy link

@sjwen98 easy but effective - thanks!

@ygr1k
Copy link

ygr1k commented Jan 14, 2022

one more solution (when restart func called outside of onExpire callback it works fine):

...
  const { seconds, minutes, isRunning, restart } = useTimer({
    expiryTimestamp: time,
  });

  if (isRunning === false) {
    const time1 = new Date();
    time1.setSeconds(time1.getSeconds() + 1800); // 30 minutes timer

    restart(time1);
  }
...

@jacinto123
Copy link

Any hope of this getting patched sometime soon? While there are ways to hack around this its frustrating to have to do it to begin with.

@mrmidaw
Copy link

mrmidaw commented Aug 9, 2022

Hello, I solved this problem like this:

export const TimerSixtySecond = ({ expiryTimestamp }) => {
const onExpire = async () => {
const time = await new Date();
time.setSeconds(time.getSeconds() + 60);
restart(time, true);
resume;
};

const {
seconds,
minutes,
hours,
days,
isRunning,
start,
pause,
resume,
restart,
} = useTimer({
expiryTimestamp,
onExpire: () => onExpire(),
autoStart: true,
});

return (
<Text Text color="red.500" fontWeight="bold" fontSize={["5xl", "8xl"]}>
{minutes}:{seconds}

);
};

@BenLooper
Copy link

BenLooper commented Sep 23, 2022

As @prpercival said, it's only going to restart the timer if the component is re-rendered.
An easy workaround then is to flip a boolean in state in the onExpire (causing a re-render), and have a useEffect restart the timer when that piece of state changes. This will restart the timer on a loop, but you can add logic to the useEffect & onExpire callback if you want to conditionally restart:

const Timer = ({ expiryTimeStamp }) => {

    const [flipState, setFlipState] = useState(true);

    useEffect(() => {
        const time = new Date();
        time.setSeconds(time.getSeconds() + 10);
        restart(time);
    }, [flipState])

    const {
        seconds,
        minutes,
        hours,
        days,
        isRunning,
        start,
        pause,
        resume,
        restart,
    } = useTimer({ expiryTimestamp, onExpire: () => setFlipState(!flipState) });


    return (
        <div style={{ textAlign: 'center' }}>
            <div style={{ fontSize: '50px' }}>
                <span>{seconds}</span>
            </div>
        </div>
    );
}

@devonpmack
Copy link

Still happening in 2023, boolean state flip works as a workaround 👍

@PlacidSerene
Copy link

The setTimeout() mentioned above is an easy work around!

@SSopin
Copy link

SSopin commented Oct 18, 2023

Quite disappointing, despite the workarounds above solving the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants