ReactJs/NextJS - automatic redirect after 5 seconds to another page

Viewed 1110
  • I am creating welcome page which should appear right after customer is logged in and this page should automatically redirect customer to another page after 5 seconds. I tried to use setState with default value of 5 seconds and then using setInterval of 1000ms, decrease it by 1 and when it comes to 0, redirect customer.

Console.log() always returns 5, so basically on frontend I always see this sentence: Welcome, you have successfully logged in, you will be redirected in.. 4

Looks like that because setRedirectSeconds() is asynchronous, it wont update state right at the moment and whenever my setInterval function starts again, redirectSeconds will still be 5 each time.

How to fix that?

Here is my code:

const Welcome: NextPage = (): ReactElement => {
const [redirectSeconds, setRedirectSeconds] = useState<number>(5);
const router = useRouter();
const query = router.query;

useEffect(() => {
    if (query?.redirect) {
        setTimeout(() => {
            const interval = setInterval(() => {
                console.log(redirectSeconds);
                if (redirectSeconds > 0) {
                    setRedirectSeconds(redirectSeconds - 1);
                } else {
                    clearInterval(interval);
                    router.push(query.redirect.toString());
                }
            }, 1000)
        }, 1000);
    }
}, []);

return (
        <div>
            Welcome, you have successfully logged in, you will be redirected in.. {redirectSeconds}
        </div>
);
};

export default Welcome;
1 Answers

Here is how I adjusted it and now it works fine:

  • I have removed setInterval and added dependancy to useEffect function. And I have added timeout of 1000ms before decreasing redirectSeconds.

     useEffect(() => {
     if (query?.redirect) {
         if (redirectSeconds == 0) {
             router.push(query.redirect.toString());
             return;
         }
    
         setTimeout(() => {
             console.log(redirectSeconds);
             setRedirectSeconds((redirectSeconds) => redirectSeconds - 1);
         }, 1000)
     }
    }, [redirectSeconds]);
    
Related