thinking react defaultvalue defaultchecked controlled javascript reactjs

javascript - defaultvalue - setstate react native



¿Hay una alternativa sincrónica de setState() en Reactjs? (7)

Según la explicación en la docs :

setState () no muta de forma inmediata this.state pero crea una transición de estado pendiente. El acceso a this.state después de llamar a este método puede devolver el valor existente.

No hay garantía de funcionamiento síncrono de las llamadas a setState y las llamadas pueden agruparse para obtener ganancias en el rendimiento.

Por lo tanto, puesto que setState() es asíncrono y no hay garantía sobre su rendimiento síncrono. ¿Hay una alternativa de setState() que es sincronizada?

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 pocas preguntas sobre Stackoverflow que son similares a esta pregunta pero no donde puedo encontrar la respuesta correcta.


Como ha leído en la documentación, NO hay alternativa de sincronización, la razón tal como se describe son mejoras de rendimiento.

Sin embargo, supongo que desea realizar una acción después de haber cambiado su estado, puede lograr esto 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>


La respuesta breve a su pregunta es: NO, reaccionar no tiene el método de sincronización setState .


No no hay. React actualizará el estado cuando lo considere oportuno, haciendo cosas como setState llamadas setState para lograr eficiencia. Le puede interesar que pueda pasar una función a setState , que toma el estado anterior, por lo que puede elegir su nuevo estado con un buen conocimiento del anterior.


Podría ajustar setState en una función que devuelva una promesa, y luego usar esta función con la palabra clave await para hacer que su código espere hasta que se aplique el estado.

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 setStateSynchronous hace que la ejecución del código se detenga hasta que la promesa devuelta por setStateSynchronous se haya resuelto, lo que solo ocurre una vez que se llama a la devolución de llamada que pasa a setState , lo que solo sucede cuando se ha aplicado el estado. Por lo tanto, la ejecución solo llega a la llamada console.log una vez que se ha aplicado la actualización de estado.

docs 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


Pude engañar a React para que llame a setState síncrona envolviendo mi código en setTimeout(() => {......this.setState({ ... });....}, 0); . Dado que setTimeout pone cosas al final de la cola de eventos de JavaScript, creo que React detecta que setState está dentro de ella y sabe que no puede confiar en una llamada setState (que se agregaría al final de la cola).


Sí, hay un método con el que podemos hacer nuestro setState síncrono. Pero su rendimiento tal vez no sea tan bueno como normalmente. Por ejemplo, tenemos

class MyComponent extends React.Component { constructor(props) { super(props); this.state = { data: 0 }; } changeState(){ console.log(''in change state'',this.state.data); this.state.data = ''new value here'' this.setState({}); console.log(''in change state after state change'',this.state.data); } render() { return ( <div> <p>{this.state.data}</p> <a onClick={this.changeState}>Change state</a> </div> ); } }

En este ejemplo, primero cambiamos el estado y luego renderizamos nuestro componente.


Si esto fuera 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 el estado se haya actualizado.

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í: docs

Nota: los documentos oficiales dicen: "En general, recomendamos usar componentDidUpdate () para dicha lógica".