Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

188
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!