De acuerdo con la explicación en los documentos :
setState() no muta inmediatamente this.state sino que crea una transición de estado pendiente. Acceder a this.state después de llamar a este método puede potencialmente devolver el valor existente.
No hay garantía de funcionamiento síncrono de las llamadas a setState y las llamadas pueden agruparse por lotes para mejorar el rendimiento.
Entonces, dado que setState() es asíncrono y no hay garantía sobre su rendimiento síncrono. ¿Existe una alternativa de setState() que sea síncrona?
Por ejemplo
//initial value of cnt:0 this.setState({cnt:this.state.cnt+1}) alert(this.state.cnt); //alert value:0 Dado que el valor de alert es un valor anterior, ¿cuál es la alternativa que dará alert value:1 usando setState() .
Hay algunas preguntas en Stackoverflow que son similares a esta pregunta, pero no puedo encontrar la respuesta correcta.
Como ha leído en la documentación, NO existe una alternativa de sincronización, la razón descrita es la mejora del rendimiento.
Sin embargo, supongo que desea realizar una acción después de haber cambiado su estado, puede lograrlo a través de:
class MyComponent extends React.Component { constructor(props) { super(props); this.state = { x: 1 }; console.log('initial state', this.state); } updateState = () => { console.log('changing state'); this.setState({ x: 2 },() => { console.log('new state', this.state); }) } render() { return ( <div> <button onClick={this.updateState}>Change state</button> </div> ); } } ReactDOM.render( <MyComponent />, document.getElementById("react") ); <div id="react"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>Podría envolver setState en una función que devuelve una promesa y luego usar esta función con la palabra clave await para hacer que su código espere hasta que se haya aplicado el estado.
Personalmente, nunca haría esto en código real, sino que simplemente pondría el código que deseo ejecutar después de la actualización de estado en la devolución de llamada de setState .
Sin nervios, aquí tienes un ejemplo.
class MyComponent extends React.Component { function setStateSynchronous(stateUpdate) { return new Promise(resolve => { this.setState(stateUpdate, () => resolve()); }); } async function foo() { // state.count has value of 0 await setStateSynchronous(state => ({count: state.count+1})); // execution will only resume here once state has been applied console.log(this.state.count); // output will be 1 } } En la función foo, la palabra clave await hace que la ejecución del código se detenga hasta que se resuelva la promesa devuelta por setStateSynchronous , lo que solo ocurre una vez que se llama a la devolución de llamada pasada a setState , lo que solo ocurre cuando se ha aplicado el estado. Por lo tanto, la ejecución solo llega a la llamada de console.log una vez que se ha aplicado la actualización de estado.
documentos para async/await:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
Si esto es necesario, sugeriría usar una devolución de llamada en su función setState (y también sugiero usar un setState funcional).
La devolución de llamada se llamará después de que se haya actualizado el estado.
Por ejemplo, tu ejemplo sería
//initial value of cnt:0 this.setState( (state) => ({cnt: state.cnt+1}), () => { alert(this.state.cnt)} )según la documentación aquí: https://facebook.github.io/react/docs/react-component.html#setstate
Nota: Los documentos oficiales dicen: "Por lo general, recomendamos usar componentDidUpdate() para dicha lógica en su lugar".