How to redirect user to a diferent path if token is expired

I'm making a simple site for a project, and i want to redirect player to a login page if the token is expired, but I'm not really sure how to do it properly, here's what I've tried, im using react-jwt to check the token

function App() {

  return (
    <div style={{display:'flex', flexDirection:'column', height:'100vh'}}>
      <Navbar/>
      <div style={{display:'flex', flex:1}}>
        <Routes>
          <Route path="/login" element ={<LoginForm/>} />
          <Route path="/signUp" element ={<SignUpForm/>} />
          <Route path="/addMovie" element= {<AddMovie/>} />
          <Route path="/" element={isExpired(localStorage.getItem('token') ? <FilmList/> : <LoginForm/> )} />
          <Route path="/details" exact element ={<MovieDetails/>} />
        </Routes>
      </div>
    </div>
  );
}

or something like

<Route path="/" 
render={props=>{
  if(isExpired(localStorage.getItem('token'))){
    return <Navigate to='/login'/>;
  }
  return <FilmList/>
}}
/>

The first one just returns nothing, and the second one gives a warning in console:

Matched leaf route at location "/" does not have an element. This means it will render an with a null value by default resulting in an "empty" page.

Is there a way to make it work ?


Solution 1:

In react-router-dom v6 gone are custom route components, and the Route component must have a valid ReactElement on the element prop. A function is incorrect. Your second snippet is close.

Create an AuthWrapper to conditionally render an Outlet for a nested route or a redirect.

const AuthWrapper = () => {
  return isExpired(localStorage.getItem('token')
    ? <Navigate to="/login" replace />
    : <Outlet />;
};

Wrap any routes you want to protect into a Route rendering the AuthWrapper.

function App() {
  return (
    <div style={{display:'flex', flexDirection:'column', height:'100vh'}}>
      <Navbar />
      <div style={{display:'flex', flex:1}}>
        <Routes>
          <Route path="/login" element={<LoginForm />} />
          <Route path="/signUp" element={<SignUpForm />} />
          <Route path="/addMovie" element={<AddMovie />} />
          <Route element={<AuthWrapper />}>
            <Route path="/" element={<FilmList />} />
          </Route>
          <Route path="/details" element={<MovieDetails />} />
        </Routes>
      </div>
    </div>
  );
}