skip to Main Content

How would I go about redirecting to another react page with react-router@6 if conditions are not met? I was attempting to use this in the body of the component, but it doesn’t seem to do anything.

const Basket = () => {
  redirect("/login")

  return (
    <div className="box">
      <h2>Basket</h2>
    </div>
  );
}

export default Basket;

Bear in mind I haven’t yet programmed the if statement, but it will eventually look like this:

if (currentUser != null) {
  <redirect here>
}

Could anyone point me in the right direction?

4

Answers


  1. Here’s an example:

    import React from 'react'
    import { Navigate} from 'react-router-dom';
    
    export default function LoginPage() {
        if (currentUser !== null) {
            return <Navigate to='/some-where-else' />
        } else {
            // Maybe a login form?
        }
    }
    
    Login or Signup to reply.
  2. I’d prefer an useEffect approach, in case currentUser is not defined or set in the first render.

    import { Redirect } from 'react-router-dom';
    
    const Basket = () => {
      useEffect(() => {
        if (!!currentUser) {
          <Redirect to="/any-route-you-want" />
        }
      }, [currentUser]);
    
      return (
        <div className="box">
            <h2>Basket</h2>
        </div>
      );
    }
    
    Login or Signup to reply.
  3. redirect is a utility function only valid in RRDv6.4+ route loader and action functions. It’s not valid to call in a React component. If you want to issue a redirect from the UI you can use either the useNavigate hook (via navigate function) to issue an imperative redirect or render the Navigate component for a declarative redirect.

    Imperative Redirect

    import { useNavigate } from 'react-router-dom';
    
    const Basket = () => {
      const navigate = useNavigate();
    
      React.useEffect(() => {
        if (!currentUser) {
          navigate("/login", { replace: true });
        }
      }, [navigate, currentUser]);
    
      ...
    
      if (!currentUser) {
        // early return to not leak basket UI, if necessary
        return null;
      }
    
      return (
        <div className="box">
          <h2>Basket</h2>
        </div>
      );
    };
    

    Declarative Redirect

    import { Navigate } from 'react-router-dom';
    
    const Basket = () => {
      ...
    
      if (!currentUser) {
        return <Navigate to="/login" replace />;
      }
    
      return (
        <div className="box">
          <h2>Basket</h2>
        </div>
      );
    };
    

    Suggestion

    Instead of checking the user’s authentication status in the routed components it likely preferable to implement protected routes instead.

    Example:

    import { Outlet, Navigate } from 'react-router-dom';
    
    const ProtectedRoute = () => {
      ...get currentUser ...
    
      if (currentUser === undefined) {
        return null; // or loading indicator/spinner/etc
       }
    
      return currentUser
        ? <Outlet />
        : <Navigate to="/login" replace />
    };
    

    Then wrap the sets of routes you want to protect.

    <Router>
      <Route element={<ProtectedRoute />}>
        <Route path="/basket" element={<Basket />} />
        ... other protected routes ...
      </Route>
      <Route path="/login" element={<Login />} />
      ... other unprotected routes ...
    </Router>
    
    Login or Signup to reply.
  4. If you want to archieve that if the User is not LoggedIn use:

    Pure React:

    import { redirect } from "react-router-dom";
    
    const loader = async () => {
      const user = await getUser(); //function which retrieves e.g. the user from DB
      if (!currentUser) {
        return redirect("/login");
      }
      return null;
    };
    

    For the Next.js (React Framework):

    useEffect() hook with useRouter(). Try something like this:

      const {currentUser} = useAuth(); //you are getting the user from DB
      const router = useRouter(); // importing the router usage
    
        useEffect(() => {
                if(!currentUser) { //if there is not user push me to the login
                    router.push('/login')  
                }
            }, [router, currentUser]) // dependencies - watch for the changes
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search