skip to Main Content

When a user logs in, I want to check if he has created his business or not. If he hasn’t he should be navigated to the onboarding page. The page keeps refreshing as if there’s a loop going on. Someone advised I put this in the protected route file. I tried doing it this way:

Homepage.jsx

const { message} = useSelector(
    (state) => state.auth
  );

 useEffect(() => {
    if (message !== "This user does not have a business account, please create one and continue") {
      navigate("/auth/onboarding");
    }
  }, [message, navigate])

I have this useEffect in the onboarding page. I suspect the loop comes from here because this toast message appears.

useEffect(() => {
    if (isError) {
      toast({
        title: "Error",
        description: message,
        status: "error",
        position: "top-right",
        duration: 5000,
        isClosable: true,
      });
    }

    if (isSuccess || organization) {
      toast({
        title: "Congrats!🎉",
        description: "Onboarding completed.",
        status: "success",
        position: "top-right",
        duration: 15000,
        isClosable: true,
      });
      navigate("/");
    }

  }, [organization, isError, isSuccess, navigate, dispatch]);

ProtectedRoute.jsx

import { Navigate, Outlet, useLocation } from "react-router-dom";
import { useSelector } from "react-redux";

export default function ProtectedRoutes() {
  const location = useLocation();
  const { user } = useSelector((store) => store.auth);
 
  let userid = localStorage.getItem("user") == null ? false : true;
  return <div>{userid ? <Outlet /> : <Navigate to="/auth/login" />}</div>;
}

Included what i tried above.

2

Answers


  1. One thing to note here is your use of useEffect and return calls. Generally, return calls in useEffect are intended for cleanup functions, and are performed on render, or on unmount. This could have adverse effects on your redirect. Try removing the return and simply calling the redirect on the condition.

    Login or Signup to reply.
  2. A far simpler implementation of this is not to use an effect.

    If the message requires a redirect, return a Redirect component (declarative redirect), if the message doesn’t require a redirect, return the actual component you want to render

    You’ll avoid a flash of content and you’ll also enjoy simpler logic in your child component because it no longer has to consider if the user also needs to be redirected or not, that’ll be handled in the parent

    TL;DR – if you’re trying to redirect a user away from a component they shouldn’t be accessing, you’ve already lost. The logic that prevents them from accessing the component in the first place should be elsewhere, not in the component they shouldn’t be accessing

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search