Estoy usando localStorage para guardar los datos del usuario al iniciar sesión. Lo he guardado llamado "jwt_data". Creé una función en un archivo js separado para recuperar esos datos como
export const auth = () => { if(localStorage.getItem('jwt_data')){ return JSON.parse(localStorage.getItem('jwt_data')) }else{ return false } }y tengo un componente de barra de navegación en reaccionar con <logotipo, barra de búsqueda, un menú desplegable>. Quería ocultar eso una vez que el usuario cierra la sesión y mostrarlo una vez que inicie sesión. Usé código como
const auth_user = auth() ........ <> {auth_user ? (// if logged in..... ) : (// if user is logged out........) </>Funcionó. Pero el problema es que no es reactivo. Necesito recargar el sitio web para ver ese efecto.
También traté de usar otros como
const [auth_user, setAuth_user] = useState(false) useEffect(() => { if(auth()) {setAuth_user(true)} else {setAuth_user(false)} })Que tienen el mismo resultado que el anterior. no se donde me equivoque Otras personas sugirieron usar redux y otras cosas, lo cual es demasiado complicado para mi mente y mi aplicación simple.
Mi app.js se ve así
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> ); }Después de iniciar sesión, me mudé a casa y, mientras lo hacía, quería eliminar todas las cosas en la barra de navegación que solo se muestran autenticadas, como en este caso y también en otros escenarios generales.
¿Algo que me esté perdiendo aquí? Gracias por su amable respuesta.
Entonces necesitas useContext en este caso.
En tu aplicación.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> ); }y luego en tu 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 */ ) }y en su componente de inicio de sesión:
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> ) }y cerrar sesión:
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> ) }Creo que el problema aquí es que ves localStorage como tu estado, lo cual no es del todo correcto en el espacio de React. Para que su componente se actualice, debe mantener esta información en un estado al que su componente pueda suscribirse. Ya sea el estado React (useState) o uno global (redux, context , etc.).
Entonces, su clave de almacenamiento local sería una forma de inicializar este estado (por ejemplo, al actualizar). Entonces, cuando cambia el estado de inicio de sesión, debe actualizar ambos.
Dado que desea simplificar las cosas, la mejor manera sería crear un estado de loggedIn de sesión en el componente de su aplicación y luego delegar en sus componentes secundarios el estado de inicio de sesión (componente de navegación) o el setter loggedIn (componente de inicio de sesión/ setLoggedIn de sesión) para actualizarlo.
Puede encontrar ejemplos sobre cómo crear ganchos de reacción que utilizan el uso de localeStorage como este . Puede encontrar el código de su aplicación a continuación, si usó el useLocalStorage del enlace, o cualquier otra implementación similar.
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> ); } Sin embargo, a medida que su aplicación se vuelve más complicada, puede reconsiderar mantener esto en un estado de reacción interno y usar el contexto en su lugar para evitar la perforación de accesorios desde el componente de su App a sus hijos.