How to handle conditional redirect in react app routes?

428 Views Asked by At

I am using a metronic theme for my react project and now I am trying to do a conditional redirect based on value from an api. I found a file called Routes.js already written and I am trying to change there. This is what it looks like

 const [request, setRequest] = useState();
 const [isUserActive, setIsUserActive] = useState(false);

  useEffect(() => {
    fetch("http://82 ...")
      .then((res) => res.json())
      .then((data) => setRequest(data));
  }, []);

  useEffect(() => {
    if (request) {
      request.isUser=== true
        ? setIsUserActive(true)
        : setIsUserActive(false);
    }
  }, [request]);

  return (
    <Switch>
      <Route path="/error" component={ErrorsPage} />

      {!isUserActive ? (
        <Redirect to="error/error-v1" />
      ) : (
        <>
          <Redirect to="/" />
          <Layout>
            <BasePage />
          </Layout>
        </>
      )}
    </Switch>
  );

When isUserActive is true, I want to go to root path but if it isn't, I want to go to error page. isUserActive now logs

false 
false 
true

But my project is always redirecting to /error/error-v1 even though the final value is true, am I missing something here ?

1

There are 1 best solutions below

1
On BEST ANSWER

You probably want to add another state for loading. The reason why is that with the current setup, once the code directs you to the /error endpoint there is no going back and it will always render the error page.

const [request, setRequest] = useState();
// vvv this was added vvv
// vvv this was added vvv
// vvv this was added vvv
const [requestLoading, setRequestLoading] = useState(true);
const [isUserActive, setIsUserActive] = useState(false);

 useEffect(() => {
   fetch("http://82 ...")
     .then((res) => res.json())
     .then((data) => setRequest(data));
 }, []);

 useEffect(() => {
   if (request) {
     // vvv this was added vvv
     // vvv this was added vvv
     // vvv this was added vvv
     setRequestLoading(false);
     request.isUser=== true
       ? setIsUserActive(true)
       : setIsUserActive(false);
   }
 }, [request]);

 return (
   // vvv this conditional rendering was added vvv
   // vvv this conditional rendering was added vvv
   // vvv this conditional rendering was added vvv
   {!requestLoading ? <Switch>
     <Route path="/error" component={ErrorsPage} />

     {!isUserActive ? (
       <Redirect to="error/error-v1" />
     ) : (
       <>
         <Redirect to="/" />
         <Layout>
           <BasePage />
         </Layout>
       </>
     )}
   </Switch> : <div />}
 );

For now all this does is render a div if the request is still loading, then it routes you based on the result once its finished