React Router v6 中的受保护路由,使用 useState,但始终 returns false

Protected Routes in React Router v6, using useState, but always returns false

这就是我想要做的。我从google获取了一个JWT,暂时存储在sessionStorage中,通过我的API发送给服务器端验证。

这是我用来环绕我的受保护元素的受保护路线。像这样

 <Route element={<PrivateRouteClient />}>  
                <Route path="/CDashboard" element={<Client_dashboard /> }>
 </Route>




import axios from 'axios';
import React, {useEffect, useState} from 'react';
import {Navigate}  from 'react-router-dom';
import {Outlet}  from 'react-router-dom';

 function PrivateRouteClient() {
  const [isAuth, setIsAuth] = useState(false);
  
  axios.post('http://localhost:8080/something/something', {credential: sessionStorage.getItem("token")})
  .then(function (res){
    console.log(Boolean(res.data["UserAuth"]));
    setIsAuth(Boolean(res.data["UserAuth"]));
    console.log("hi");
    return isAuth;
  })
  console.log(isAuth)
  return isAuth ? <Outlet /> : <Navigate to="/login/Client" />;
}

  
export default PrivateRouteClient

而且我无法使路由异步,因为它将 return 一个承诺,这不是一个有效的 React 组件,它会抛出错误。 不太明白我哪里做错了!

感谢阅读和帮助!

有几个问题,(1) 您发出 POST 请求是无意的副作用,(2) 代码是异步的,而 React 组件的主体是同步的。

使用安装 useEffect 挂钩发出 POST 请求并等待请求解决。使用中间 isAuth 状态值“保持”,直到 POST 请求以任何一种方式解决用户是否通过身份验证。

function PrivateRouteClient() {
  const [isAuth, setIsAuth] = useState(); // initially undefined

  useEffect(() => {
    axios.post(
      'http://localhost:8080/something/something',
      { credential: sessionStorage.getItem("token") },
    )
      .then(function (res){
        console.log(Boolean(res.data["UserAuth"]));
        setIsAuth(Boolean(res.data["UserAuth"]));
        return isAuth;
      });
  }, []);

  console.log(isAuth);

  if (isAuth === undefined) return null; // or loading indicator, etc...

  return isAuth ? <Outlet /> : <Navigate to="/login/Client" />;
}

Drew 的回答对我帮助很大,谢谢! useEffect 是必经之路!

当我们运行这个片段时,log的“初始”值是“undefined”[这意味着isAuth的类型也是undefined]。当我们 运行 和 axios.post 时,isAuth 被设置为一个字符串,而不是布尔值,所以我们不能真正转换是使用 Boolean() 方法。

 function PrivateRouteClient() {
  const [isAuth, setIsAuth] = useState();
  console.log("initial")
  console.log(isAuth)

  useEffect(() => {
    axios.post('http://localhost:8080/api/something',{credential: sessionStorage.getItem("token")}
    ).then(function (res){
        console.log("setting IsAuth")
        console.log(res.data["UserAuth"])
        // console.log(Boolean(res.data["UserAuth"]));
        setIsAuth(res.data["UserAuth"]);
        return isAuth;
      });
  });

  console.log(isAuth);

  if (isAuth === undefined) return null; // or loading indicator, etc...

  return isAuth==="true" ? <Outlet /> : <Navigate to="/login/Client" />;
}

附上日志以供参考。