¿Por qué llamar al método setState de reacción no muta el estado inmediatamente?

Resuelto Salah Eddine Taouririt asked hace 9 años • 10 respuestas

Estoy leyendo la sección Formularios dereaccionajsdocumentación y acabo de probar este código para demostrar onChangeel uso ( JSBIN ).

var React= require('react');

var ControlledForm= React.createClass({
    getInitialState: function() {
        return {
            value: "initial value"
        };
    },

    handleChange: function(event) {
        console.log(this.state.value);
        this.setState({value: event.target.value});
        console.log(this.state.value);

    },

    render: function() {
        return (
            <input type="text" value={this.state.value} onChange={this.handleChange}/>
        );
    }
});

React.render(
    <ControlledForm/>,
  document.getElementById('mount')
);

Cuando actualizo el <input/>valor en el navegador, el segundo console.logdentro de la handleChangedevolución de llamada se imprime igual valueque el primero console.log. ¿Por qué no puedo ver el resultado this.setState({value: event.target.value})en el alcance de la devolución de handleChangellamada?

Salah Eddine Taouririt avatar Jun 11 '15 20:06 Salah Eddine Taouririt
Aceptado

De la documentación de React :

setState()no muta inmediatamente this.statesino que crea una transición de estado pendiente. Acceder this.statedespués de llamar a este método puede potencialmente devolver el valor existente. No hay garantía de funcionamiento sincrónico de las llamadas setStatey las llamadas pueden agruparse para mejorar el rendimiento.

Si desea que se ejecute una función después de que se produzca el cambio de estado, pásela como una devolución de llamada.

this.setState({value: event.target.value}, function () {
    console.log(this.state.value);
});
Michael Parker avatar Jun 11 '2015 14:06 Michael Parker

Como se menciona en la documentación de React, no hay garantía de setStateque se active sincrónicamente, por lo que console.logpuede devolver el estado antes de actualizarlo.

Michael Parker menciona pasar una devolución de llamada dentro del setState. Otra forma de manejar la lógica después del cambio de estado es mediante el componentDidUpdatemétodo del ciclo de vida, que es el método recomendado en los documentos de React.

Generalmente recomendamos usar componenteDidUpdate() para dicha lógica.

Esto es particularmente útil cuando se pueden activar setStatemensajes de correo electrónico sucesivos y desea activar la misma función después de cada cambio de estado. En lugar de agregar una devolución de llamada a cada uno setState, puede colocar la función dentro del componentDidUpdate, con una lógica específica dentro si es necesario.

// example
componentDidUpdate(prevProps, prevState) {
  if (this.state.value > prevState.value) {
    this.foo();  
  }
}
Yo Wakita avatar Mar 04 '2017 23:03 Yo Wakita