如果令牌过期,如何将用户重定向到不同的路径

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

我正在为一个项目制作一个简单的网站,如果令牌已过期,我想将玩家重定向到登录页面,但我不太确定如何正确地做到这一点,这就是我所拥有的试过了,我正在使用 react-jwt 检查令牌

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>
  );
}

或类似

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

第一个 returns 什么都没有,第二个在控制台给出警告:

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.

有没有办法让它工作?

一种解决方案是使用 react-router-dom 中的 Redirect 组件。

Fo 进入您的 FilmList 组件并在渲染部分执行以下检查:

if (isExpired(localStorage.getItem('token')){
 return <Redirect to='/login' />
}

在你之前 return 你的 'normal' FilmList

对于不支持重定向的 RRDv6,您可以使用导航组件:

if (isExpired(localStorage.getItem('token')){
 return <Navigate to='/login' replace={true} />
}

react-router-dom v6 中,自定义路由组件消失了,Route 组件 必须 element 属性上有一个有效的 ReactElement。功能不正确。您的第二个代码段已完成。

创建 AuthWrapper 以有条件地为嵌套路由或重定向呈现 Outlet

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

将您要保护的任何路由包装到 Route 呈现 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>
  );
}