React 路由保护失败,因为状态没有改变

问题描述 投票:0回答:1

我正在尝试实现调用后端进行身份验证的路由保护功能。后端响应没问题,但是前端给了我一个奇怪的行为,我卡了一周但没有发现问题。

在代码中,ok 状态总是给我错误的值,我认为这是因为异步代码。

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

function RequireAuth() {
    const [ok, setOk] = useState(false);
    const fetchUser = async () => {
        try {
            const { data } = await axios.get('http://localhost:5555/api/current-user', {
                withCredentials: true,
                credentials: 'include',
            });
            console.log(data);
            //data.ok === true
            if (data.ok) {
                setOk(true);
            }
        } catch (err) {
            console.log(err);
        }
    };
    useEffect(() => {
        fetchUser();
    }, []);
    console.log(ok);
    // ok === false
    return ok ? <Outlet /> : <Navigate to="/login" />;
}

export default RequireAuth;
reactjs async-await state
1个回答
0
投票

当你的组件 RequireAuth 挂载时,它会立即返回基于初始状态 ok 的 JSX,这是 false。这意味着您的组件将在 fetchUser 异步函数有机会更新状态之前尝试导航到 /login

添加一个加载程序并仅在获取完成后检查导航如何

 const [ok, setOk] = useState(false);
    const [loading, setLoading] = useState(true); // Added loading state

    const fetchUser = async () => {
        try {
            const { data } = await axios.get('http://localhost:5555/api/current-user', {
                withCredentials: true,
                credentials: 'include',
            });
            if (data.ok) {
                setOk(true);
            }
        } catch (err) {
            console.log(err);
        } finally {
            setLoading(false); 
        }
    };

    useEffect(() => {
        fetchUser();
    }, []);

    if (loading) {
        return <div>Loading...</div>;
    }

    return ok ? <Outlet /> : <Navigate to="/login" />;
}
© www.soinside.com 2019 - 2024. All rights reserved.