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 ?
CodePudding user response:
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>
);
}
CodePudding user response:
One solution would be to use the Redirect component from react-router-dom.
Fo into your FilmList component and in the rendering part do the following check:
if (isExpired(localStorage.getItem('token')){
return <Redirect to='/login' />
}
before you return your 'normal' FilmList
FOR RRDv6 that doesn't support Redirect you can use the Navigate component:
if (isExpired(localStorage.getItem('token')){
return <Navigate to='/login' replace={true} />
}
