我想根據用戶登錄狀態渲染路由。所以,我創建了一個函式來檢查用戶是否使用 axios 在后端進行了身份驗證,并在 App 組件的 useEffect 中呼叫該函式并將回應存盤在 useState 中。然后我在 Route 組件的元素中使用條件。如果用戶通過身份驗證,則將用戶重定向到主頁。如果沒有,請重定向到登錄頁面。但問題是當我嘗試從 url 欄輸入路由時,即使我通過了身份驗證,我總是會被重定向到登錄頁面。
這些是我的代碼(我洗掉了一些不相關的代碼看起來更干凈)
function App() {
const navigate = useNavigate();
const [isLoggedIn, setIsLoggedIn] = useState("NOT_LOGGED_IN");
const [user, setUser] = useState({});
const verifyLogin = async () => {
const res = await axios({
url: "http://localhost:5000/isloggedin",
method: "get",
withCredentials: true
})
if (res.data.isLoggedIn && isLoggedIn === "NOT_LOGGED_IN") {
setIsLoggedIn("LOGGED_IN");
setUser(res.data.user)
} else if (!res.data.isLoggedIn && isLoggedIn === "LOGGED_IN") {
setIsLoggedIn("NOT_LOGGED_IN");
setUser({})
}
}
useEffect(() => {
verifyLogin()
}, [])
return (
<div className="App">
<Routes>
<Route path='/' element={isLoggedIn === "LOGGED_IN" ? <Home isLoggedIn={isLoggedIn} user={user} /> : <Navigate to="/login" />} exact />
<Route path='/register' element={<Register handleRegister={handleRegister} registerError={registerError} />} />
<Route path='/register/:userId/info' element={isLoggedIn === "LOGGED_IN" ? <RegisterInfo handleRegister={handleRegister} registerError={registerError} /> : <Navigate to={"/register"} />} />
<Route path='/login' element={<Login isLoggedIn={isLoggedIn} handleLogin={handleLogin} logout={logout} />} />
</Routes>
</div >
);
}
如果我的文字讓你感到困惑,我很抱歉。我英語不太好。
uj5u.com熱心網友回復:
問題
問題是您的初始isLoggedIn狀態與您的未經身份驗證的狀態相匹配。當應用程式最初加載并且您嘗試訪問任何路由時,應用程式使用此"NOT_LOGGED_IN"初始isLoggedIn狀態值并確定用戶未登錄并相應地重定向。
解決方案
常見的解決方案是從既未經過身份驗證也未經過身份驗證的“不確定”狀態開始,并且有條件地不渲染任何內容,或者加載指示器等......除了路由組件或重定向之外的任何內容。
例子:
function App() {
const navigate = useNavigate();
const [isLoggedIn, setIsLoggedIn] = useState(); // <-- initially undefined
const [user, setUser] = useState({});
useEffect(() => {
const verifyLogin = async () => {
const res = await axios({
url: "http://localhost:5000/isloggedin",
method: "get",
withCredentials: true
});
if (res.data.isLoggedIn && isLoggedIn === "NOT_LOGGED_IN") {
setIsLoggedIn("LOGGED_IN");
setUser(res.data.user);
} else if (!res.data.isLoggedIn && isLoggedIn === "LOGGED_IN") {
setIsLoggedIn("NOT_LOGGED_IN");
setUser({});
}
};
verifyLogin();
}, []);
if (isLoggedIn === undefined) { // <-- check if undefined
return null; // or loading indicator, etc...
}
return (
<div className="App">
<Routes>
<Route
path='/'
element={isLoggedIn === "LOGGED_IN"
? <Home isLoggedIn={isLoggedIn} user={user} />
: <Navigate to="/login" />
}
/>
<Route
path='/register'
element={(
<Register
handleRegister={handleRegister}
registerError={registerError}
/>
)}
/>
<Route
path='/register/:userId/info'
element={isLoggedIn === "LOGGED_IN"
? (
<RegisterInfo
handleRegister={handleRegister}
registerError={registerError}
/>
)
: <Navigate to={"/register"} />
}
/>
<Route
path='/login'
element={(
<Login
isLoggedIn={isLoggedIn}
handleLogin={handleLogin}
logout={logout}
/>
)}
/>
</Routes>
</div >
);
}
進一步的建議
- 將 state 和 auth 驗證抽象
isLoggedIn到 React 背景關系中。 - 將受保護的路由邏輯抽象為包裝器或布局組件。
這使您的代碼更加DRY。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/436101.html
上一篇:如何對我的登錄系統進行復雜查詢?
