我正在使用 localStorage 在登錄時保存用戶資料。我將它保存為“jwt_data”。我在 saperate js 檔案上創建了一個函式來檢索該資料
export const auth = () => {
if(localStorage.getItem('jwt_data')){
return JSON.parse(localStorage.getItem('jwt_data'))
}else{
return false
}
}
我有一個導航欄組件,可以與 < logo , searchbar, a dropdown> 反應。我想隱藏一次用戶注銷并顯示一次我登錄。我用代碼作為
const auth_user = auth()
........
<>
{auth_user ? (// if logged in..... ) : (// if user is logged out........)
</>
它確實奏效了。但問題是它不是反應性的。我需要重新加載網站才能看到效果。
我也嘗試使用其他如
const [auth_user, setAuth_user] = useState(false)
useEffect(() => {
if(auth()) {setAuth_user(true)}
else {setAuth_user(false)}
})
與之前的結果相同。我不知道我錯在哪里。其他人建議使用redux和東西,這對我的想法和我的簡單應用來說太復雜了。
我的 app.js 看起來像這樣
import React from 'react';
import Nav from './Nav';
import Home from './Home';
import Login from './Login';
import Logout from './Logout';
function App() {
return (
<div className="App">
<Router>
<Router>
<Nav/>
<Routes>
<Route exact path="/home" element={<Home/>}/>
<Route exact path="/login" element={<Login/>}/>
<Route exact path="/logout" element={<Logout/>}/>
</Routes>
</Router>
</div>
);
}
登錄后,我搬到了家中,在這樣做的同時,我想洗掉導航欄中所有僅顯示經過身份驗證的內容,例如在這種情況下以及其他一般情況下。
我在這里缺少什么嗎?感謝您的友好回答。
uj5u.com熱心網友回復:
所以在這種情況下你需要 useContext 。
在你的 app.js 中
import React, { useContext } from "react";
export const AuthContext = React.createContext(null);
function App() {
const [authContext, setAuthContext] = useState(localStorage.getItem("auth"));
return (
<AuthContext.Provider value={authContext, setAuthContext}>
<Router>
<Nav/>
<Routes>
<Route exact path="/home" element={<Home/>}/>
<Route exact path="/login" element={<Login/>}/>
<Route exact path="/logout" element={<Logout/>}/>
</Routes>
</Router>
</AuthContext.Provider>
);
}
然后在你的 Nav.js
import React, { useContext } from "react";
import { AuthContext } from "./App.js"
function Nav() {
const [authContext, setAuthContext] = useContext(AuthContext);
return (
authContext
? /*Navbar with user stuff*/
: /*Empty Navbar */
)
}
并在您的登錄組件中:
import React, { useContext } from "react";
import { AuthContext } from "./App.js"
function Login() {
const [authContext, setAuthContext] = useContext(AuthContext);
const login = () => {
const jwt = "jwt"; // fetch your jwt
localStorage.setItem("auth", jwt)
setAuthContext(jwt);
}
return (
<div>Login form</div>
)
}
和注銷:
import React, { useContext } from "react";
import { AuthContext } from "./App.js"
function Logout() {
const [authContext, setAuthContext] = useContext(AuthContext);
const logout = () => {
localStorage.setItem("auth", null)
setAuthContext(null);
}
return (
<button onClick={logout}>Logout button</button>
)
}
uj5u.com熱心網友回復:
我認為這里的問題是你看到的localStorage是你的狀態,這在 React 空間中并不完全正確。為了更新您的組件,您需要將此資訊保持在您的組件可以訂閱的狀態。React 狀態(useState)或全域狀態(redux、context等)。
那么您的語言環境存盤密鑰將是初始化此狀態的一種方式(例如,在重繪 時)。因此,當登錄狀態發生變化時,您必須同時更新它們。
由于您想讓事情變得簡單,最好的方法是loggedIn在您的 App 組件中創建一個狀態,然后將loggedIn狀態(Nav 組件)或setLoggedInsetter(登錄/注銷組件)委托給您的子組件來更新它。
您可以找到有關如何創建使用localeStoragelike this one 的react hooks 的示例。如果您使用useLocalStorage來自鏈接的代碼或任何其他類似的實作,您可以在下面找到您的應用程式的代碼。
import React from 'react';
import Nav from './Nav';
import Home from './Home';
import Login from './Login';
import Logout from './Logout';
import useLocaleStorage from 'somewhere'
function App() {
const [loggedIn, setLoggedIn] = useLocalStorage('jwt_data', false);
return (
<div className="App">
<Router>
<Router>
<Nav loggedIn={loggedIn} /> // and hide what's need to be hidden
<Routes>
<Route exact path="/home" element={<Home/>}/>
<Route exact path="/login" element={<Login setLoggedIn={setLoggedIn} />}/>
<Route exact path="/logout" element={<Logout setLoggedIn={setLoggedIn} />}/>
</Routes>
</Router>
</div>
);
}
但是,隨著您的應用程式變得更加復雜,您可能會重新考慮將其保持在內部反應狀態并使用背景關系來避免從您的App組件到其子組件的prop 鉆取。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/351794.html
標籤:javascript 反应 本地存储
