React Router:如何在 API returns 响应之前停止重定向?

React Router: How to stop redirecting until API returns a response?

我有一个登录页面,但它通过调用后端来验证路由器上的登录。如果用户通过身份验证,后端 returns 响应 200,否则响应 400。

这是我的私有路由代码块

export default function PrivateRoute({ component: Component, ...rest }: { component: any }) {
    // 
    const [userLoggedIn, setUserLoggedIn] = useState(false);

    useEffect(() => {
        // If acess_token cannot be found, set expiration to current time to force login
        const jwtToken = localStorage.getItem('sycamore_access_token')

        axiosInstance.post('/auth/authenticatetoken/', {
            token: jwtToken,
            user: localStorage.getItem("user")
        })
            .then(res => {
                setUserLoggedIn(true)
                console.log(userLoggedIn, "A")
            })
            .catch(error => {
                setUserLoggedIn(false)
                console.log(userLoggedIn, "B")
            })

    }, [])

和 returns 组件(如果其已通过身份验证)

return (
        <React.Fragment>
            {console.log(userLoggedIn)}
            <Route
                {...rest}
                render={(props) =>
                    (userLoggedIn) ? (
                        <Component {...props} />
                    ) : (
                        <Redirect
                            to={{ pathname: '/Login', state: { from: props.location } }}
                        />
                    )
                }
            />
        </React.Fragment>

这里的问题是状态 userLoggedIn 似乎没有立即更新,returns false -> authenticated -> true,然后它已经将我重新重定向回登录页面。知道为什么会发生这种情况或如何解决这个问题吗?

The problem here is that the state userLoggedIn does not seem to update immediately

没错,一旦 post 请求 return 得到响应,userLoggedIn 就会更改。

您可以添加状态 loading/inProgress 并使用它来显示加载 component/text 直到 API return 响应。

const [userLoggedIn, setUserLoggedIn] = useState(false);
const [loading, setLoading] = useState(true);

useEffect(() => {
  const jwtToken = localStorage.getItem('sycamore_access_token');
  
  // initial value of loading is `true` so setLoading(true) is unnecessary

  axiosInstance
    .post('/auth/authenticatetoken/', {
      token: jwtToken,
      user: localStorage.getItem('user'),
    })
    .then((res) => {
      setUserLoggedIn(true);
      console.log(userLoggedIn, 'A');
    })
    .catch((error) => {
      setUserLoggedIn(false);
      console.log(userLoggedIn, 'B');
    })
    .finally(() => {
        // setting loading to false
        setLoading(false);
    });
}, []);

如果 loading 为真,现在您可以 return 提早。这将阻止重定向检查,直到 loading 更改为 false。

if(loading) return <p>Loading...</p>

return (<React.Fragment>...);