Redirect shows the sign in page partially before redirecting in next js react

Viewed 4613

I have a simple app where if a user is signed in and if the user manually tries to go to /signin page he is redirected to the index page. I'm using nextjs and to achieve this is I run a function in useEffect where boolean is checked true if so I use Router.push is used to redirect the user to the index page. The functionality works fine I see a few milliseconds of sign-in page before redirecting to the index page. Why is that? is it because the useEffect is called every time after the component is rendered? basically I want to run that code before rendering component and useEffect runs after the component is rendered. I want basically to run the code something like componentWillMount. How do I do it in the functional component? or is there any other solution?

const SigninComponent = () => {

  



useEffect(() => {
  
  isAuth() && Router.push(`/`);
}, []);

return(
   // components 
);
}
2 Answers

Thats because useEffect will only run after component has mounted.
You can use different solutions :

  1. Conditional rendering, add a loading field to state that is true by default, when it is true your component will render something like a spinner/loading component, if isAuth() return false then you will render something else (most likely a login form).
    Pseudocode:
const SigninComponent = () => {
  const [loading, setLoading] = useState(true);
  useEffect(() => {
    if(isAuth()){
      Router.push(`/`);
    }else{
      setLoading(false)
    }
  }, []);

  if(!loading){
    return <Login />
  }else{
    return <MyloaderComponent />
  }
}
  1. Use HOC component, similar to above but you will wrap the above logic in a HOC component
  2. Use getServerSideProps and run isAuth() server-side instead that client-side, if you redirect inside getServerSideProps the component will not render at all. (you can use getServerSideProps only in pages)
export const getServerSideProps = async (ctx) => {
  const auth = await isAuth() // or other any logic, like read cookies...

  if (!auth) {
      const { res } = ctx;
      res.setHeader("location", "/");
      res.statusCode = 302;
      res.end();
      return;
  }

  return {
      props: {}, // or return user
  };
};

You may consider using Redirect Component

const SigninComponent = () => {
  if (isAuth()) return <Redirect to="/" />
  
  return(
     // components 
  );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Related