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

React受保护路由出现不应有的重定向问题

问题修复:登录状态判断前提前触发重定向

你的问题核心是loading状态在异步请求完成前就被设置为false,导致loggedIn还保持初始的false值时,Protected组件就执行了重定向逻辑,哪怕后续请求成功更新了loggedIn,也已经来不及阻止重定向了。

修复步骤:

把setLoading(false)移到异步请求的finally回调中,确保只有在登录状态请求完成(成功或失败)后,才结束加载状态,让Protected组件根据最终的loggedIn值判断是否重定向。

修改后的代码:

App组件部分:

function App() {
    const [user, setUser] = useState(null);
    const [loggedIn, setLoggedIn] = useState(false);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        axios.get('/me')
            .then(res => {
                setUser(res.data)
                setLoggedIn(true);
            })
            .catch(err => {
                setLoggedIn(false);
            })
            // 无论请求成功或失败,都在请求完成后结束加载
            .finally(() => {
                setLoading(false);
            });
    }, []);

    const router = createBrowserRouter([
        {
            path: '/',
            element: (
                <Protected user={user} loggedIn={loggedIn} loading={loading}>
                  <Home />
                </Protected>
            ),
        },
        // 其他路由配置...
    ]);

    return <RouterProvider router={router} />;
}

Protected组件(无需修改):

const Protected = ({ user, loggedIn, loading, children }) => {
    if (loading) {
        return null; // 加载中时不渲染任何内容,避免提前判断
    }

    if (!loggedIn) {
        return <Navigate to="/login" replace />;
    }

    return children;
};

补充说明:

原代码中useEffect的return语句会在组件挂载后立刻触发(空依赖数组的useEffect,其清理函数会在组件卸载时执行),这就导致loading在axios请求还没响应时就变成了false,Protected组件此时读取到的loggedIn还是初始的false,直接触发重定向。用finally回调可以保证不管请求成功还是失败,都会在请求结束后更新loading状态,确保Protected组件判断的是最终的登录状态。

内容的提问来源于stack exchange,提问作者Noah Dennis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 19:20:49