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

112
Vistas
Reaccionar orden de llamada setTimeout

Estoy tratando de entender cómo funciona este componente React (está destinado a retrasar la representación de sus hijos):

 function Delayed({ children, wait = 500 }) { const [show, setShow] = React.useState(false); React.useEffect(() => { console.log("effect"); const timeout = window.setTimeout(() => { console.log("setTimeout", show); setShow(true); }, wait); return () => { console.log("cleanup"); window.clearTimeout(timeout); }; }); console.log("render", show); return show === true ? children : null; }

Produce una salida como esta:

 1. render false 2. effect 3. setTimeout false 4. render true 5. cleanup 6. effect 7. setTimeout true 8. render true

Entiendo el orden hasta la última línea. ¿De dónde viene el último registro de procesamiento? El booleano ya es verdadero en este punto, por lo que setState no debería activar una nueva representación, pero lo hace de alguna manera. Supongo que me estoy perdiendo algo muy obvio.

Códigos y caja: https://codesandbox.io/s/fancy-fire-6t380

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Con useEffect usted "le dice a React que su componente necesita hacer algo después de renderizar " ( ref ). Agregué un registro adicional a su código, para obtener los tiempos:

 function time(msg) { return '[' + new Date().getTime() + '] ' + msg } function Delayed({ children, wait = 500 }) { const [show, setShow] = React.useState(false); React.useEffect(() => { console.log(time("effect")); const timeout = window.setTimeout(() => { console.log(time("setTimeout"), timeout, show); setShow(true); }, wait); console.log(time("created timeout"), timeout); return () => { console.log(time("cleanup"), timeout); window.clearTimeout(timeout); }; }); console.log(time("render"), show); return show === true ? children : null; }

Produce:

 [1641339330296] render false [1641339330315] effect [1641339330315] created timeout 16 [1641339330816] setTimeout 16 false [1641339330818] render true [1641339330824] cleanup 16 [1641339330825] effect [1641339330825] created timeout 24 [1641339331325] setTimeout 24 true [1641339331327] render true

Por lo tanto, el tiempo de espera del efecto se activa como se esperaba después del primer render false , pero se activa nuevamente después del render true y establece otro tiempo de espera, que no es deseado. Simplemente puede protegerse contra este caso con el if (!show) como se muestra a continuación:

 function Delayed({ children, wait = 500 }) { const [show, setShow] = React.useState(false); React.useEffect(() => { console.log(time("effect")); if (!show) { // <--- THE CHANGE IS HERE const timeout = window.setTimeout(() => { console.log(time("setTimeout"), timeout, show); setShow(true); }, wait); console.log(time("created timeout"), timeout); return () => { console.log(time("cleanup"), timeout); window.clearTimeout(timeout); }; } }); console.log(time("render"), show); return show === true ? children : null; }

Producción:

 [1641339821991] render false [1641339822010] effect [1641339822010] created timeout 16 [1641339822510] setTimeout 16 false [1641339822513] render true [1641339822517] cleanup 16 [1641339822518] effect
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