Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

195
Vistas
React Router Dom, la redirección ocurre antes de que se ejecute el código dentro de useEffect

Estoy intentando usar el gancho useEffect de React para ejecutar un comando de búsqueda y almacenar el resultado en el estado. Luego me gustaría usar ese valor de estado para representar condicionalmente un componente React Route. Tengo problemas para establecer el valor de esa variable en el estado antes de que el componente ejecute la instrucción condicional y devuelva el componente Ruta.

Código expreso:

 app.post('/refresh_token_from_db', async (req: Request, res: Response) => { res.send(true) })

Rutas protegidas:

 import { Navigate, Outlet } from 'react-router-dom' import { useState, useEffect } from 'react'; function ProtectedRoutes() { const [token, setToken] = useState<boolean>(false); // Data does't start loading // until *after* component is mounted useEffect(() => { const go = async () => { await fetch('/refresh_token_from_db', { method: 'POST', mode: 'same-origin', redirect: 'follow', credentials: 'same-origin', headers: { 'content-type': 'application/json', 'Accept': 'application/json' }, }).then(res => res.json()) .then(data => { console.log("Should run 1st", data); setToken(data) }) } go() }, []); console.log("Should run 2nd", token); return ( token ? <Outlet /> : <Navigate to="/login" /> ); } export default ProtectedRoutes
about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

Si lo entiendo correctamente, desea que su componente espere la respuesta de búsqueda y luego decida si lo redirigirá para iniciar sesión o no.

En ese caso, agregue otro estado llamado isWaiting y configúrelo inicialmente como verdadero, luego llame a setIsWaiting(false) justo debajo de setToken(data);

Finalmente, cambia el retorno a esto:

 return ( token && !isWaiting ? <Outlet /> : <Navigate to="/login" /> );
about 4 years ago · Juan Pablo Isaza Denunciar

0

Obtener los datos, así como ejecutar la devolución de llamada de un useEffect y mutar el state en React son tareas asincrónicas. Lo que significa este código:

 return ( token ? <Outlet /> : <Navigate to="/login" /> );

podría ejecutarse antes, y cuál está causando esa redirección anterior. Lamentablemente, aquí no se puede dictar el orden de ejecución, o muy difícilmente. Una solución es usar un estado adicional, lo llamé checking , así:

 import { useEffect, useState } from 'react'; import { Navigate, Outlet } from 'react-router-dom'; function ProtectedRoutes() { const [token, setToken] = useState<boolean>(false); const [checking, setIsChecking] = useState<boolean>(true); // Data does't start loading // until *after* component is mounted useEffect(() => { const go = async () => { await fetch('/refresh_token_from_db', { method: 'POST', mode: 'same-origin', redirect: 'follow', credentials: 'same-origin', headers: { 'content-type': 'application/json', 'Accept': 'application/json' }, }).then(res => res.json()) .then(data => { console.log("Should run 1st", data); setToken(data) setIsChecking(false) }) } go() }, []); console.log("Should run 2nd", token); if(checking) return <p>Loading...</p> return ( token ? <Outlet /> : <Navigate to="/login" /> ); } export default ProtectedRoutes
about 4 years ago · Juan Pablo Isaza Denunciar

0

Tema

Su estado de token inicial enmascara o coincide con el estado "no autenticado" y es por eso que el componente Navigate se procesa en el ciclo de procesamiento inicial y navega a la ruta de inicio de sesión.

Solución

No utilice el mismo estado inicial que los valores de estado "autenticados" o "no autenticados". Use este valor de estado "indeterminado" para convertir condicionalmente en nulo o algún indicador de carga. Además, no mezcle async/await con las cadenas Promise, se considera antipatrón. Tenga en cuenta que fetch puede devolver Promesas rechazadas y debe manejarlas en consecuencia.

Ejemplo:

 function ProtectedRoutes() { const [token, setToken] = useState<boolean | undefined>(); // <-- initially undefined // Data does't start loading // until *after* component is mounted useEffect(() => { const go = async () => { try { const response = await fetch('/refresh_token_from_db', { method: 'POST', mode: 'same-origin', redirect: 'follow', credentials: 'same-origin', headers: { 'content-type': 'application/json', 'Accept': 'application/json' }, }); const data = await response.json(); setToken(data); } catch(error) { // catch/handle any errors // set unauthenticated status setToken(false); } }; go(); }, []); if (token === undefined) { return null; // or loading indicator/spinner/etc... } return token ? <Outlet /> : <Navigate to="/login" replace />; }
about 4 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 Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda