isAuthenticated始终为null
我正在尝试比较令牌是否过期,但isAuthenticated始终为空
import React, {useEffect, useState} from 'react';
import {Navigate} from 'react-router-dom'
import jwtDecode from "jwt-decode";
interface IPrivateRoute {
children: React.ReactNode;
}
const PrivateRoute = ({children}: IPrivateRoute) => {
const [isAuthenticated, setIsAuthenticated] = useState<boolean | null>(null)
useEffect(() => {
let token = localStorage.getItem('token')
if (token) {
let decodedToken:number = jwtDecode<any>(token).exp;
let date:number = new Date().getTime() / 1000;
console.log(decodedToken <= date)
if (decodedToken <= date) {
setIsAuthenticated(true)
} else {
setIsAuthenticated(false)
}
} else {
setIsAuthenticated(false)
}
})
return (
<>
{isAuthenticated ? children : <Navigate to='/login'/>}
</>
);
};
export default PrivateRoute;
我认为问题在于初始渲染上的isAuthenticated
isnull
,这是一个伪值,并且导航到"/login"
,从而卸载此PrivateRoute
包装组件。当组件仍处于挂载状态时,useEffect
永远无法将状态更新为任何有意义的状态。
你可能有几个选择:
-
在
isAuthenticated
状态稳定的情况下无条件渲染(或加载指示器等…(然后有条件渲染children
或Navigate
。const PrivateRoute = ({ children }: IPrivateRoute) => { const [isAuthenticated, setIsAuthenticated] = useState<boolean | null>(null); useEffect(() => { const token = JSON.parse(localStorage.getItem('token')); if (token) { const decodedToken: number = jwtDecode<any>(token).exp; const date: number = new Date().getTime() / 1000; setIsAuthenticated(decodedToken <= date); } else { setIsAuthenticated(false); } }); if (isAuthenticated === null) return null; return isAuthenticated ? children : <Navigate to='/login' replace />; };
-
提供一个状态初始值设定项函数,以提供您在初始渲染中查找的有效布尔值
true
|false
isAuthenticated
。const initializeState = () => { const token = JSON.parse(localStorage.getItem('token')); if (token) { const decodedToken: number = jwtDecode<any>(token).exp; const date: number = new Date().getTime() / 1000; return decodedToken <= date; } return false; };
const PrivateRoute = ({ children }: IPrivateRoute) => { const [isAuthenticated, setIsAuthenticated] = useState<boolean>(initializeState); useEffect(() => { const token = JSON.parse(localStorage.getItem('token')); if (token) { const decodedToken: number = jwtDecode<any>(token).exp; const date: number = new Date().getTime() / 1000; setIsAuthenticated(decodedToken <= date); } else { setIsAuthenticated(false); } }); return isAuthenticated ? children : <Navigate to='/login' replace />; };