Home > Blockchain >  Next.JS Abort fetching component for route: "/login"
Next.JS Abort fetching component for route: "/login"

Time:08-15

I was developing a useUser Hook for per-page authentication. I have implemented the useUser hook normally and Redirecting works fine accordingly. But I am getting the above error.

Abort fetching component for route: "/login"

How can I fix useUserHook to solve it??

//useUser.tsx
const useUser = ({ redirectTo, redirectIfFound }: IParams) => {
  const { data, error } = useRequest("authed", isAuthed);

  const user = data?.data;
  const hasUser = user;

  useEffect(() => {
    if (!redirectTo) return;
    if (
      // If redirectTo is set, redirect if the user was not found.
      (redirectTo && !redirectIfFound && !hasUser) ||
      // If redirectIfFound is also set, redirect if the user was found
      (redirectIfFound && hasUser)
    ) {
      Router.push(redirectTo);
    }
  }, [redirectTo, redirectIfFound, hasUser]);

  return error ? null : user;
};
//index.tsx
const Home: NextPage = () => {
  const user = useUser({ redirectTo: "/login" });

  if (user === undefined || user === false) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      <Head>
        
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <div>Home</div>
    </div>
  );
};

UseRequest Hook returns true and false as return values.

CodePudding user response:

useEffect gets called multiple times as you probably know, especially with more than just one dependency, and calling router.push multiple times within the same next.js page causes an error I think.

Try ensuring that you only call router.push exactly once with the help of state:


const [calledPush, setCalledPush] = useState(false); // <- add this state

// rest of your code [...]

 useEffect(() => {
    if (!redirectTo) return;
    if (
      (redirectTo && !redirectIfFound && !hasUser) ||
      (redirectIfFound && hasUser)
    ) {
      let calledPushLatest;
      setCalledPush(latest => {
          calledPushLatest = latest;
          return latest;
      }
// ^ ensure we get the latest state, because react-state is actually "async" under the hood and takes a bit to reflect updates which may make you call router.push multiple times again
       
      if(calledPushLatest) return; // router.push has already been called

      // proceed to redirect
      setCalledPush(true);
      Router.push(redirectTo);
    }
  }, [redirectTo, redirectIfFound, hasUser]);

  return error ? null : user;
};

  • Related