[英]React - redirect to login page when not authenticated
This is my primary react file:这是我的主要反应文件:
// App.tsx
const App: FC = () => {
const isLoggedIn: boolean = localStorage.getItem('logged_user') !== null;
return (
<BrowserRouter>
<Routes>
<Route path="/main" element={isLoggedIn ? <Main/> : <Navigate to='/login'/>}/>
<Route path="/about" element={isLoggedIn ? <About/> : <Navigate to='/login'/>}/>
<Route path="/login" element={<Login/>}/>
</Routes>
</BrowserRouter>
);
}
export default App;
After logging in, I store the user in local storage.登录后,我将用户存储在本地存储中。
I want to achieve the behaviour of redirections to the /login page when the user is not authenticated (when it is not stored in localstorage).我想实现在用户未通过身份验证时重定向到 /login 页面的行为(当它未存储在本地存储中时)。
Generally, the above approach works but only sometimes.通常,上述方法有效,但仅在某些时候有效。 Sometimes, when I go to '/main' , I would get redirected to '/login' even though I was logged in. I assume this is caused by React's nature of re-renders.有时,当我 go 到'/main'时,即使我已登录,我也会被重定向到'/login' 。我认为这是由 React 的重新渲染性质引起的。
How can I approach this?我该如何处理?
I'm guessing the redirect to "/login" works the first time, you log in, then try to navigate to "/main" or "/about" and are getting redirected back to "/login" until you do something like a page reload and read any persisted "logged_user" state and then get stuck not being to log out and get redirected back to "/login".我猜重定向到“/login”第一次工作,你登录,然后尝试导航到“/main”或“/about”并被重定向回“/login”,直到你做类似的事情页面重新加载并读取任何持久的“logged_user”state,然后卡住不退出并重定向回“/login”。
You should store the isLoggedIn
value in local state, initialized from localStorage, and provide a way within the app to toggle the state.您应该将isLoggedIn
值存储在本地 state 中,从 localStorage 初始化,并在应用程序中提供一种方法来切换 state。 Use an useEffect
hook to persist local state changes back to localStorage.使用useEffect
挂钩将本地 state 更改保留回 localStorage。
Example:例子:
const App: FC = () => {
const [isLoggedIn, setIsLoggedIn] = useState<boolean>(
() => localStorage.getItem('logged_user') !== null
);
useEffect(() => {
localStorage.setItem('logged_user', JSON.stringify(isLoggedIn));
}, [isLoggedIn]);
const logIn = () => setIsLoggedIn(true);
// pass this callback to components you want to allow logging out
// it will update the local state and then get persisted
const logOut = () => setIsLoggedIn(false);
return (
<BrowserRouter>
<Routes>
<Route path="/main" element={isLoggedIn ? <Main/> : <Navigate to='/login'/>}/>
<Route path="/about" element={isLoggedIn ? <About/> : <Navigate to='/login'/>}/>
<Route path="/login" element={<Login onLogIn={logIn} />}/>
</Routes>
</BrowserRouter>
);
}
The way I like to do it, is to create a <PrivateLink />
component, so that it is clear that whatever route is nested requires an authenticated user.我喜欢这样做的方式是创建一个<PrivateLink />
组件,因此很明显任何嵌套的路由都需要经过身份验证的用户。
const PrivateRoute = (props: { children: React.ReactNode }): JSX.Element => {
const { children } = props
const isLoggedIn: boolean = localStorage.getItem('logged_user') !== null;
const location = useLocation()
return isLoggedIn ? (
<>{children}</>
) : (
<Navigate
replace={true}
to="/login"
state={{ from: `${location.pathname}${location.search}` }}
/>
)
}
Then in your App.tsx然后在你的 App.tsx
const App: FC = () => (
<BrowserRouter>
<Routes>
<Route path="/main" element={<PrivateRoute> <Main/> </PrivateRoute>}/>
<Route path="/about" element={<PrivateRoute> <About/> </PrivateRoute>}/>
<Route path="/login" element={<Login/>}/>
</Routes>
</BrowserRouter>
)
As an added extra, the from
variable that is passed to the state in the <PrivateRoute />
component, allows you to redirect the user back to whichever page they came from after logging in.作为一个额外的附加功能,在<PrivateRoute />
组件中传递给 state 的from
变量允许您在登录后将用户重定向回他们来自的任何页面。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.