我需要保護我的反應應用程式的一些路由,為此我創建了一個私有路由組件,如下所示:
import React from 'react';
import {useAuth} from "../../context/AuthContextProvider";
import {Navigate} from "react-router-dom";
import {useLocation} from "react-router";
const PrivateRoute = ({children}) => {
const {user, isAuthenticating, isAuthenticated} = useAuth();
const location = useLocation();
console.log(user, isAuthenticating, isAuthenticated);
return isAuthenticated ? children : <Navigate to="/sign-in" state={{from: location}} replace/>;
}
export default PrivateRoute;
在身份驗證背景關系提供程式中,我檢查用戶是否已登錄,如下所示:
import React, {createContext, useContext, useEffect, useState} from "react";
import {useMeMutation} from "../data/user";
const AuthContext = createContext();
export const useAuth = () => useContext(AuthContext);
const AuthContextProvider = ({children}) => {
const {mutate: me} = useMeMutation();
const [auth, setAuth] = useState({
user: null,
isAuthenticating: null,
isAuthenticated: null
});
useEffect(() => {
checkAuthentication();
}, []);
const revalidate = () => {
return me({}, {
onSuccess: ({data}) => {
console.log(data);
setAuth({
user: data,
isAuthenticating: false,
isAuthenticated: true
});
},
onError: (error) => {
if ((error.response && error.response.status === 401) ||
(error.response && error.response.status === 403)) {
setAuth({
user: null,
isAuthenticating: false,
isAuthenticated: false
});
}
},
});
};
const checkAuthentication = () => {
if (auth.isAuthenticated === null) {
revalidate();
}
};
return (
<AuthContext.Provider value={{
...auth,
revalidate
}}>{children}</AuthContext.Provider>
);
};
export default AuthContextProvider;
此代碼的問題是登錄組件在 api 端檢查用戶之前顯示。我的路線是這樣的:
<Routes>
<Route element={<PublicLayout/>}>
{publicRoutes.map(({component: Component, path, exact}) => (
<Route
path={`/${path}`}
key={path}
exact={exact}
element={<Component/>}
/>
))}
</Route>
<Route element={<PrivateRoute><PrivateLayout/></PrivateRoute>}>
{privateRoutes.map(({component: Component, path, exact}) => (
<Route
path={`/${path}`}
key={path}
exact={exact}
element={<Component/>}
/>
))}
</Route>
</Routes>
uj5u.com熱心網友回復:
在私有路由組件中,我需要停止這兩種狀態的渲染:
當用戶第一次來到登錄頁面時,isAuthenticated 的值應該為 null 并且當該值為 false 時,會呈現私有路由,
當用戶單擊登錄按鈕時,我需要將 isAuthenticating 設定為 true,在這種情況下,用戶的狀態尚不清楚,因此我還需要阻止私有路由的呈現
const PrivateRoute = ({children}) => { const {user, isAuthenticating, isAuthenticated} = useAuth(); const location = useLocation(); if (isAuthenticated === null || isAuthenticating === true) { return null; } return isAuthenticated ? children : <Navigate to="/sign-in" state={{from: location}} replace/>; }
在背景關系提供程式中,我需要在呼叫 api 的開頭指定 isAuthenticating,如下所示:
const revalidate = () => {
setAuth({
user: null,
isAuthenticating: true,
isAuthenticated: false
});
return me({}, {}
...
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/444558.html
