isAuthenticated is always null



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;

我认为问题在于初始渲染上的isAuthenticatedisnull,这是一个伪值,并且导航到"/login",从而卸载此PrivateRoute包装组件。当组件仍处于挂载状态时,useEffect永远无法将状态更新为任何有意义的状态。

你可能有几个选择:

  1. isAuthenticated状态稳定的情况下无条件渲染(或加载指示器等…(然后有条件渲染childrenNavigate

    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 />;
    };
    
  2. 提供一个状态初始值设定项函数,以提供您在初始渲染中查找的有效布尔值true|falseisAuthenticated

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

最新更新