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

207
Vistas
¿Por qué la configuración del estado en componentDidMount requiere que setTimeout funcione?

Tengo un componente que se parece al siguiente (sí, sé que existen ganchos React...). También he creado un ejemplo de CodeSandbox .

 export class App extends React.Component { state = { loadingStatus: "idle" }; componentDidMount() { debugger; setTimeout(() => { this.setState({ loadingStatus: "loading" }); }, 1); setInterval(() => { const loadingStatus = this.state.loadingStatus === "loading" ? "complete" : "loading"; this.setState({ loadingStatus }); }, 3000); } render() { const { loadingStatus } = this.state; return ( <div> <div>loadingStatus: {this.state.loadingStatus}</div> <div role="status"> {loadingStatus === "loading" && ( <img alt="loading" src="https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif?20151024034921" /> )} {loadingStatus === "complete" && ( <span className="visually-hidden">Loading has completed</span> )} </div> {loadingStatus === "complete" && ( <div>Content has loaded. The page will reload again momentarily.</div> )} </div> ); } }

Este componente demuestra cómo crear un indicador de carga de página que sea accesible para los usuarios de lectores de pantalla. La clave es el uso de un elemento con role="status" que anunciará cuando cambie su contenido. Necesita contener:

  • nada inicialmente para que, cuando sí tenga contenido, se anuncie el nuevo contenido.
  • el indicador de carga cuando el componente está en estado de carga, lo que debería ocurrir inmediatamente después de que se monte el componente.
  • un elemento visualmente oculto después de que se complete la carga que anunciará a los usuarios de lectores de pantalla que la carga se completó.

El problema que tengo es que cuando cambio el estado de carga de "inactivo" a "cargando" en el componente DidMount, no se "registra" en el DOM a menos que lo ajuste en un setTimeout (), incluso solo 1 ms demora. Si no tengo setTimeout(), no se anuncia el cambio de contenido en mi elemento role="status" .

Lo interesante es que, si elimina setTimeout() y abre las herramientas de desarrollo en el navegador, el debugger; se rompe y puede ver que la interfaz de usuario se representa cuando el estado es "inactivo". Esto me tiene confundido por qué es necesario un retraso.

Para ser claros, el problema es que, sin setTimeout(), el anuncio inicial de "carga" no ocurre. Necesitará un lector de pantalla (por ejemplo, NVDA) para probar.

Gracias por adelantado.

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

0

Se llama al método componentDidMount después de que se haya renderizado el componente. Es por eso que puede verlo cuando agrega la declaración del depurador.

Llamar setState dentro de componentDidMount activará una segunda llamada para render . Que lee el nuevo estado y actualiza el DOM.

No estoy seguro de por qué estaba usando setInterval pero si simplifica su ejemplo, en realidad funciona de la manera que esperaría.

 componentDidMount() { this.setState({ loadingStatus: 'loading' }); setTimeout(() => { this.setState({ loadingStatus: 'complete' }); }, 3000); }

Lo que provoca el siguiente flujo:

  • estado = { estado de carga: 'inactivo' }
  • prestar
  • componenteDidMount
  • setState({ estado de carga: 'cargando' })
  • prestar
  • 3 segundos después... setState({ loadingStatus: 'complete' })
  • prestar

En el ejemplo anterior setTimeout(..., 3000) representa una llamada API simulada. Lo más probable es que desee realizar una operación asincrónica como esta:

 componentDidMount() { this.setState({ loadingStatus: 'loading' }); fetch('/your/api/endpoint').then(response => { // do something with the response this.setState({ loadingStatus: 'complete' }); }); }

Si aún tiene problemas con él después de probar el método anterior, podría deberse a que setState es asíncrono y los cambios que realice se pueden procesar por lotes si ocurren en un flujo de ejecución continuo. Envolver su código en una devolución de llamada de requestAnimationFrame garantizará que el renderizado anterior esté completo antes de actualizar el estado.

 componentDidMount() { requestAnimationFrame(() => { this.setState({ loadingStatus: 'loading' }); fetch('/your/api/endpoint').then(response => { // do something with the response this.setState({ loadingStatus: 'complete' }); }); }); }
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