You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React子路由无法渲染:PrivateRoutes状态更新异常求助

React 私有路由状态更新异常问题解决

我编写了PrivateRoutes.js用于校验用户认证状态,以此决定渲染Profile组件或跳转到404页面。调用后端isUSerAuth接口后,console.log(data.auth)返回true,但console.log(isloggedin)始终显示undefined,导致路由直接跳转到404,无法正常访问Profile页面。

原私有路由代码:

import React, { useEffect, useState } from "react";
import { Navigate } from "react-router-dom";

const PrivateRoutes = ({ children }) =>{

const [isloggedin, setLoggedin] = useState()

const isUserAuth = async() =>{
    try {
      const response = await fetch('http://localhost:3001/isUSerAuth',{
        method: "GET",
        headers: { "x-access-token": localStorage.getItem("token") },   
      });
      const data = await response.json()
      console.log(data.auth)
      if(data.auth === true){
        setLoggedin(true)
      }else{
        setLoggedin(false)
      }
      console.log(isloggedin)
    } catch (error) {
      console.log(error.message)
    }
  }
  useEffect(()=>{
      isUserAuth()
  })

return (
    isloggedin ? children : <Navigate to ="/404" />
);

}

export default PrivateRoutes

路由配置代码:

<Route path='/profile' element={
    <PrivateRoutes>
        <Profile />
    </PrivateRoutes>
} />

问题根源分析

  • 初始状态与首次渲染逻辑冲突:useState()未设置初始值,默认是undefined,组件首次渲染时直接触发Navigate跳转404,此时接口校验请求还未完成。
  • setState异步特性:setLoggedin是异步更新操作,调用后不会立刻同步修改状态值,所以紧接着的console.log(isloggedin)只能拿到旧的初始值。
  • useEffect无限循环:未给useEffect设置依赖数组,组件每次渲染都会重复调用isUserAuth,引发不必要的接口请求和状态更新。

修复方案与优化代码

import React, { useEffect, useState } from "react";
import { Navigate } from "react-router-dom";

const PrivateRoutes = ({ children }) =>{
  // 用null表示"正在校验认证状态"的中间状态
  const [isloggedin, setLoggedin] = useState(null)

  const isUserAuth = async() =>{
    try {
      const response = await fetch('http://localhost:3001/isUSerAuth',{
        method: "GET",
        headers: { "x-access-token": localStorage.getItem("token") },   
      });
      const data = await response.json()
      // 直接根据接口返回值设置状态
      setLoggedin(data.auth === true)
    } catch (error) {
      console.log(error.message)
      // 请求出错时默认标记为未认证
      setLoggedin(false)
    }
  }

  // 空依赖数组确保仅组件挂载时执行一次校验
  useEffect(()=>{
    isUserAuth()
  }, [])

  // 监听状态变化,查看最新的认证状态
  useEffect(() => {
    console.log("当前认证状态:", isloggedin)
  }, [isloggedin])

  // 校验过程中显示加载提示,避免直接跳转
  if (isloggedin === null) {
    return <div>正在验证身份...</div>
  }

  return isloggedin ? children : <Navigate to="/404" />;
}

export default PrivateRoutes

内容的提问来源于stack exchange,提问作者Tarek Gharbi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:54:21