如何解决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;
可选优化
- 可以把token校验结果缓存到全局状态(Context/Redux)或者本地存储中,避免每次切换路由都重复发起校验请求,提升体验
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
相关产品推荐
相关产品推荐

