• Empleos
  • Sobre nosotros
  • profesionales
    • Inicio
    • Empleos
    • Cursos y retos
  • empresas
    • Inicio
    • Publicar vacante
    • Nuestro proceso
    • Precios
    • Evaluaciones
    • Nómina
    • Blog
    • Comercial
    • Calculadora de salario

0

206
Vistas
React.js, el componente de autenticación no redirige correctamente

Auth este componente de autenticación y funciona bien. Excepto que no redirige si el usuario no autenticado intenta visitar /dashboard .

El backend al recibir la solicitud /api/me , conoce al usuario por tener la cookie. Entonces tengo una técnica de autenticación (Cookie-Session).

 export const UserContext = createContext(); const Auth = ({ children }) => { const [user, setUser] = useState(null); const [gotUser, setGotUser] = useState(false); const navigate = useNavigate(); const getUser = async () => { const res = await fetch('/api/me'); const data = await res.json(); setUser(data); if (user) { setGotUser(true); } }; useEffect(() => { if (!gotUser) { getUser(); } }, [user, gotUser, navigate]); if (!user) { navigate('/login'); } console.log(user); return <UserContext.Provider value={user}>{children}</UserContext.Provider>; };

Entonces, el problema principal es que no se realizó la redirección. Además, el user pasado al contexto no se actualiza correctamente. Tal vez porque estoy confundido acerca de qué usar en useEffect .

Cualquier ayuda es apreciada.

almost 3 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Problemas

Hay un par de problemas:

  1. El estado "no autenticado" coincide con el estado "Todavía no lo sé" ( es decir, el valor del estado inicial ) y el componente se está redirigiendo demasiado pronto. Debe esperar hasta que se confirme el estado del user .
  2. La función de navigate se llama como un efecto secundario no intencional directamente en el cuerpo del componente. Mueva la llamada de navigate a un gancho useEffect o represente el componente Navigate para ejecutar la acción de navegación imperativa.

Solución

Utilice un estado de user inicial undefined y verifíquelo explícitamente antes de ejecutar la acción de navegación o representar el componente UserContext.Provider .

 const Auth = ({ children }) => { const [user, setUser] = useState(); // <-- initially undefined const navigate = useNavigate(); const getUser = async () => { try { const res = await fetch('/api/me'); const data = await res.json(); setUser(data); // <-- ensure defined, ie user object or null value } catch (error) { // handler error, set error state, etc... setUser(null); // <-- set to null for no user } }; useEffect(() => { if (user === undefined) { getUser(); } }, [user]); if (user === undefined) { return null; // <-- or loading indicator, spinner, etc } // No either redirect to log user in or render context provider and app return user ? <Navigate to="/login" replace /> : <UserContext.Provider value={user}>{children}</UserContext.Provider>; };
almost 3 years ago · Juan Pablo Isaza Denunciar

0

useEffect se ejecuta después de que se procesa su JSX, por lo que a medida que se crea su código, en una página, actualice esto if (!user) que llama a navigate('/login') siempre pasará, ya que antes de que useEffect haga su trabajo, user es null , ese valor inicial que le diste a useState . Sin embargo, no está redirigiendo porque la navigate no funciona dentro de JSX, debe reemplazarse con Navigate el componente.

Además, en getUser , tiene esto if (user) solo después de setUser(data) , eso no funcionaría bien ya que user no se actualizará de inmediato, ya que actualizar un state es una tarea asíncrona que surte efecto después de un re-redner .

Para solucionar sus problemas, puede agregar un estado de checking , devolver algún cargador mientras se verifica al usuario. También puede optimizar un poco su código en general, como deshacerse de ese estado gotUser :

 export const UserContext = createContext(); const Auth = ({ children }) => { const [user, setUser] = useState(null); const [checking, setChecking] = useState(true); const getUser = async () => { try { const res = await fetch("/api/me"); const data = await res.json(); setUser(data); } catch (error) { setUser(null); } finally { setChecking(false); } }; useEffect(() => { if (!user) { getUser(); } }, [user]); if (checking) { return <p>Checking...</p>; } if (!user) { return <Navigate to="/login" replace /> } return <UserContext.Provider value={user}>{children}</UserContext.Provider>; }; export default Auth;
almost 3 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recomiéndame algunas ofertas
Necesito ayuda