Estado del componente

¿Qué hace setState?

setState() programa una actualización al objeto estado de un componente. Cuando el estado cambia, el componente responde volviendo a renderizar.

¿Cuál es la diferencia entre state y props?

props (abreviatura de ”properties”) y state son objetos planos de JavaScript. Mientras ambos contienen información que influye en el resultado del render, son diferentes debido a una importante razón: props se pasa al componente (similar a los parámetros de una función) mientras que state se administra dentro del componente (similar a las variables declaradas dentro de una función).

Aquí hay algunos buenos recursos para leer más sobre cuándo usar props vs. estado:

¿Por qué setState me está dando el valor incorrecto?

En React, tanto this.props como this.state representan los valores renderizados, es decir, lo que hay actualmente en la pantalla.

Las llamadas a setState son asíncronas; no te fíes de que this.state refleje el nuevo valor inmediatamente después de llamar a setState. Pasa una función de actualización en lugar de un objeto si necesitas calcular valores en función del estado actual (revisa a continuación para más detalles).

Ejemplo de código que no se comportará como se espera:

incrementCount() {
  // Nota: esto *no* funcionará como se espera.
  this.setState({count: this.state.count + 1});
}

handleSomething() {
  // Digamos que `this.state.count` se inicia en 0.
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();
  // Cuando React rerenderiza el componente, `this.state.count` será 1, pero tu esperabas 3.

  // Esto es porque la función anterior `incrementCount()` lee de `this.state.count`,
  // pero React no actualiza `this.state.count` hasta que el componente se vuelve a renderizar.
  // Entonces `incrementCount()` termina leyendo `this.state.count` como 0 cada vez, y lo establece a 1.

  // ¡La solución se describe a continuación!
}

Ve a continuación cómo solucionar este problema.

¿Cómo actualizo el estado con valores que dependen del estado actual?

Pasa una función en lugar de un objeto a setState para asegurarte de que la llamada siempre use la versión más actualizada del estado (ver más abajo).

¿Cuál es la diferencia entre pasar un objeto o una función en setState?

Pasar una función de actualización te permite acceder al valor del estado actual dentro del actualizador. Dado que las llamadas a setState son por lotes, esto te permite encadenar actualizaciones y asegurarte de que se construyan una encima de otra en lugar de generar conflictos:

incrementCount() {
  this.setState((state) => {
    // Importante: lee `state` en vez de `this.state` al actualizar.
    return {count: state.count + 1}
  });
}

handleSomething() {
  // Digamos que `this.state.count` inicia en 0.
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();

  // Si lees `this.state.count` ahora, aún sería 0.
  // Pero cuando React vuelva a renderizar el componente, será 3.
}

Aprende más sobre setState

¿Cuándo setState es asíncrono?

Actualmente, setState es asíncrono dentro de los controladores de eventos.

Esto garantiza, por ejemplo, que si Parent y Child llaman a setState durante un evento de click, Child no se renderiza dos veces. En su lugar, React “vacía” las actualizaciones del estado al final del evento del navegador. Esto se traduce en mejoras significativas de rendimiento en aplicaciones más grandes.

Este es un detalle de implementación, así que evita confiar en él directamente. En las versiones futuras, React realizará actualizaciones por lotes por defecto en más casos.

¿Por qué React no actualiza this.state de forma sincrónica?

Como se explicó en la sección anterior, React intencionalmente “espera” hasta que todos los componentes llamen a setState() en sus controladores de eventos antes de comenzar a rerenderizar. Esto aumenta el rendimiento al evitar rerenderizados innecesarios.

Sin embargo, es posible que aún te estés preguntando por qué React no solo actualiza ‘this.state’ inmediatamente sin volver a renderizar.

Hay dos razones principales:

  • Esto rompería la consistencia entre props y state, causando problemas que son muy difíciles de depurar.
  • Esto haría que algunas de las nuevas funcionalidades en las que estamos trabajando sean imposibles de implementar.

Este comentario de GitHub profundiza en los ejemplos específicos.

¿Debo usar una biblioteca de manejo de estado como Redux o MobX?

Tal vez.

Es una buena idea conocer primero React, antes de agregar bibliotecas adicionales. Puedes construir aplicaciones bastante complejas usando solo React.