ReactJs/NextJS -5秒后自动重定向到其他页面

2g32fytz  于 2022-11-23  发布在  React
关注(0)|答案(3)|浏览(213)
  • 我正在创建欢迎页面,该页面应在客户登录后立即显示,并且该页面应在5秒后自动将客户重定向到另一个页面。我尝试使用setState,默认值为5秒,然后使用setInterval,将其减少1,当达到0时,重定向客户。
    Console.log()总是返回5,所以基本上在前端我总是看到这句话:欢迎,您已成功登录,您将被重定向到..4

看起来是这样的,因为setRedirectSeconds()是异步的,它不会立即更新状态,每当我的setInterval函数再次启动时,redirectSeconds每次仍然是5。
如何解决这个问题?
下面是我的代码:

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;
sqyvllje

sqyvllje1#

下面是我如何调整它,现在它的工作正常:

  • 我已经删除了setInterval并添加了对useEffect函数的依赖性。并且我在减少redirectSeconds之前添加了1000ms的超时。
useEffect(() => {
 if (query?.redirect) {
     if (redirectSeconds == 0) {
         router.push(query.redirect.toString());
         return;
     }

     setTimeout(() => {
         console.log(redirectSeconds);
         setRedirectSeconds((redirectSeconds) => redirectSeconds - 1);
     }, 1000)
 }
}, [redirectSeconds]);
aurhwmvo

aurhwmvo2#

您可以使用下面的自定义挂钩来实现此功能。

import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';

export default function useRedirectAfterSomeSeconds(redirectTo, seconds = 5) {
  const [secondsRemaining, setSecondsRemaining] = useState(seconds);
  const router = useRouter();

  useEffect(() => {
    if (secondsRemaining === 0) router.push('/');

    const timer = setTimeout(() => {
      setSecondsRemaining((prevSecondsRemaining) => prevSecondsRemaining - 1);
      if (secondsRemaining === 1) router.push(redirectTo);
    }, 1000);

    return () => {
      clearInterval(timer);
    };
  }, [router, secondsRemaining, redirectTo]);

  return { secondsRemaining };
}

用法示例:

import Head from 'next/head';
import useRedirectAfterSomeSeconds from '../hooks/useRedirectAfterSomeSeconds';

export default function ErrorPage() {
  const { secondsRemaining } = useRedirectAfterSomeSeconds('/', 5);

  return (
    <>
      <Head>
        <title>Page not found - redirecting in 5 seconds</title>
      </Head>
      <main>
        <h1>404</h1>
        <p>
          This page cannot be found. Redirecting to homepage in
          {secondsRemaining} {secondsRemaining > 1 ? 'seconds' : 'second'}.
        </p>
      </main>
    </>
  );
}
k5ifujac

k5ifujac3#

设置顶级状态变量。当它达到0时,重定向用户

import { useNavigate } from "react-router-dom";

  const [count, setCount] = useState(5);

内部useEffect写入setInterval,在1000ms后将计数减1

const navigate = useNavigate();
useEffect(()=>{
   // each second count=count-1
   const interval=setTimeInterval(()=>{
            setCount((updatedCount)=>updatedCcount-1)
        },1000)
    // if count===0 redirect

    count==0 && navigate(`/${query.redirect.toString()}`)

    // always clear the timeers in return function
    return ()=>{
          clearIntercal(interval)
    }

},[count,navigate])

然后编写消息。

p>
      This page cannot be found. Redirecting to homepage in
      {count} {count > 1 ? 'seconds' : 'second'}.
    </p>

相关问题