You need to enable JavaScript to run this app. 如何解决React保护路由的Promise pending问题且不修改ProtectedRoute为async
优惠活动
大模型
产品
解决方案
定价
更多

如何解决React保护路由的Promise pending问题且不修改ProtectedRoute为async

问题核心原因

JS 中所有异步函数的返回值天然是 Promise 类型,不存在同步等待异步请求(比如接口校验token)返回结果再继续执行同步代码的方案,你当前的写法不可能直接拿到布尔值类型的result,必须借助 React 状态管理异步请求的状态和结果。

修正后的ProtectedRoute实现

不需要修改为async组件,通过useState+useEffect处理异步逻辑:

import React, { useState, useEffect } from "react";
import { Redirect, Route } from "react-router-dom";
import { CheckToken } from "./RequestAction"

function ProtectedRoute({ component: Component, ...restOfProps }) {
  // 管理校验加载状态
  const [isLoading, setIsLoading] = useState(true);
  // 管理token校验结果
  const [isAuth, setIsAuth] = useState(false);

  useEffect(() => {
    // 异步执行token校验
    const verifyToken = async () => {
      const res = await CheckToken();
      setIsAuth(res);
      setIsLoading(false);
    };
    verifyToken();
  }, []);

  // 校验中展示加载态,避免未出结果就跳转
  if (isLoading) return <div>权限校验中...</div>;

  return (
    <Route
      {...restOfProps}
      render={(props) =>
        isAuth ? <Component {...props} /> : <Redirect to="/login/" />
      }
    />
  );
}

export default ProtectedRoute;

可选优化

  1. 可以把token校验结果缓存到全局状态(Context/Redux)或者本地存储中,避免每次切换路由都重复发起校验请求,提升体验
  2. CheckToken可以简化写法,不需要混合async/await和then/catch:
import axios from "axios";
async function CheckToken() {
  try {
    const res = await axios.get(`http://localhost:5000/protected`, {
      withCredentials: true
    });
    return res.data.status === "success";
  } catch (err) {
    return false;
  }
}

内容的提问来源于stack exchange,提问作者Thanat Mathanukraw

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 20:12:02