will receive react props prevstate getderivedstatefromprops example component await async javascript multithreading asynchronous reactjs

javascript - receive - setstate async



¿Por qué es setState en reactjs Async en lugar de Sync? (7)

Acabo de descubrir que en react this.setState() función en cualquier componente es asíncrona o se llama después de completar la función en la que se llamó.

Ahora busqué y encontré este blog ( http://www.bennadel.com/blog/2893-setstate-state-mutation-operation-may-be-synchronous-in-reactjs.htm )

Aquí descubrió que setState es asíncrono (se llama cuando la pila está vacía) o se sincroniza (se llama tan pronto como se llama) dependiendo de cómo se activó el cambio de estado.

Ahora estas dos cosas son difíciles de digerir

  1. En el blog, la función setState se llama dentro de una función updateState , pero lo que activó la función updateState no es algo que una función llamada sabría.
  2. ¿Por qué harían setState asíncrono ya que JS es un lenguaje de subproceso único y este setState no es una WebAPI o una llamada al servidor, por lo que debe hacerse solo en el hilo de JS? ¿Están haciendo esto para que Re-Rendering no detenga a todos los oyentes de eventos y otras cosas, o hay algún otro problema de diseño?

1) setState acciones setState son asíncronas y se agrupan para obtener ganancias de rendimiento. Esto se explica en la documentación de setState .

setState () no muta inmediatamente this.state pero crea una transición de estado pendiente. Acceder a this.state después de llamar a este método puede devolver el valor existente. No hay garantía de operación síncrona de llamadas a setState y las llamadas pueden ser agrupadas para obtener ganancias de rendimiento.


2) ¿Por qué harían setState asíncrono ya que JS es un lenguaje único y este setState no es una WebAPI o una llamada al servidor?

Esto se debe a que setState altera el estado y provoca el procesamiento. Esta puede ser una operación costosa y hacerla sincrónica puede dejar al navegador sin respuesta.

Por lo tanto, las llamadas a setState son asíncronas y están agrupadas para una mejor experiencia y rendimiento de la interfaz de usuario.


Buen artículo aquí https://github.com/vasanthk/react-bits/blob/master/patterns/27.passing-function-to-setState.md

// assuming this.state.count === 0 this.setState({count: this.state.count + 1}); this.setState({count: this.state.count + 1}); this.setState({count: this.state.count + 1}); // this.state.count === 1, not 3 Solution this.setState((prevState, props) => ({ count: prevState.count + props.increment }));

o pasar callback this.setState ({.....},callback)

https://medium.com/javascript-scene/setstate-gate-abc10a9b2d82 https://medium.freecodecamp.org/functional-setstate-is-the-future-of-react-374f30401b6b


Imagina incrementar un contador en algún componente:

class SomeComponent extends Component{ state = { updatedByDiv: '''', updatedByBtn: '''', counter: 0 } divCountHandler = () => { this.setState({ updatedByDiv: ''Div'', counter: this.state.counter + 1 }); console.log(''divCountHandler executed''); } btnCountHandler = () => { this.setState({ updatedByBtn: ''Button'', counter: this.state.counter + 1 }); console.log(''btnCountHandler executed''); } ... ... render(){ return ( ... // a parent div <div onClick={this.divCountHandler}> // a child button <button onClick={this.btnCountHandler}>Increment Count</button> </div> ... ) } }

Hay un controlador de recuento adjunto a los componentes primarios y secundarios. Esto se hace a propósito para que podamos ejecutar setState () dos veces dentro del mismo contexto de evento de clic, pero desde 2 controladores diferentes.

Como podríamos imaginar, un evento de un solo clic en el botón ahora activaría estos dos controladores ya que el evento burbujea desde el objetivo hasta el contenedor más externo durante la fase de burbujeo.

Por lo tanto, btnCountHandler () se ejecuta primero, se espera que incremente la cuenta a 1 y luego se ejecuta divCountHandler (), que se espera que incremente la cuenta a 2.

Sin embargo, el recuento solo aumenta a 1, como puede inspeccionar en las herramientas React Developer.

Esto prueba que reaccionan

  • pone en cola todas las llamadas setState

  • vuelve a esta cola después de ejecutar el último método en el contexto (el divCountHandler en este caso)

  • fusiona todas las mutaciones de objetos que ocurren dentro de múltiples llamadas setState en el mismo contexto (todas las llamadas a métodos dentro de una sola fase de evento es el mismo contexto, por ejemplo) en una sintaxis de mutación de un solo objeto (la fusión tiene sentido porque es por eso que podemos actualizar las propiedades de estado de forma independiente en setState () en primer lugar)

  • y lo pasa a un solo setState () para evitar volver a renderizar debido a múltiples llamadas setState () (esta es una descripción muy primitiva del procesamiento por lotes).

Código resultante ejecutado por react:

this.setState({ updatedByDiv: ''Div'', updatedByBtn: ''Button'', counter: this.state.counter + 1 })

Para detener este comportamiento, en lugar de pasar objetos como argumentos al método setState, se pasan devoluciones de llamada.

divCountHandler = () => { this.setState((prevState, props) => { return { updatedByDiv: ''Div'', counter: prevState.counter + 1 }; }); console.log(''divCountHandler executed''); } btnCountHandler = () => { this.setState((prevState, props) => { return { updatedByBtn: ''Button'', counter: prevState.counter + 1 }; }); console.log(''btnCountHandler executed''); }

Después de que el último método finaliza la ejecución y cuando reacciona vuelve a procesar la cola setState, simplemente llama a la devolución de llamada para cada setState en cola, pasando el estado del componente anterior.

De esta forma, reaccionar garantiza que la última devolución de llamada en la cola actualice el estado en el que todas sus contrapartes anteriores han tenido manos.


Puede llamar a una función después de que se haya actualizado el valor del estado:

this.setState({foo: ''bar''}, () => { // Do something here. });

Además, si tiene muchos estados para actualizar a la vez, setState todos dentro del mismo setState :

En lugar de:

this.setState({foo: "one"}, () => { this.setState({bar: "two"}); });

Solo haz esto:

this.setState({ foo: "one", bar: "two" });


Puede usar el siguiente ajuste para realizar llamadas de sincronización

this.setState((state =>{ return{ something } })


Sé que esta pregunta es antigua, pero ha causado mucha confusión a muchos usuarios reactivos durante mucho tiempo, incluyéndome a mí. Recientemente, Dan Abramov (del equipo de reacción) acaba de escribir una gran explicación de por qué la naturaleza de setState es asíncrona:

https://github.com/facebook/react/issues/11527#issuecomment-360199710

setState está destinado a ser asíncrono, y hay algunas buenas razones para ello en la explicación vinculada de Dan Abramov. Esto no significa que siempre será asíncrono, principalmente significa que simplemente no puede depender de que sea sincrónico . ReactJS toma en consideración muchas variables en el escenario en el que está cambiando el estado, para decidir cuándo se debe actualizar el state y volver a procesar su componente.
Un ejemplo simple para demostrar esto es que si llama a setState como reacción a una acción del usuario, entonces el state probablemente se actualizará de inmediato (aunque, una vez más, no puede contar con él), por lo que el usuario no sentirá cualquier retraso, pero si llama a setState en reacción a una respuesta de llamada ajax o algún otro evento que no sea activado por el usuario, entonces el estado podría actualizarse con un ligero retraso, ya que el usuario realmente no sentirá este retraso, y mejorará el rendimiento al esperar agrupar múltiples actualizaciones de estado y volver a generar el DOM menos veces.


Sí, setState () es asíncrono.

Desde el enlace: https://reactjs.org/docs/react-component.html#setstate

  • React no garantiza que los cambios de estado se apliquen de inmediato.
  • setState () no siempre actualiza inmediatamente el componente.
  • Piense en setState () como una solicitud en lugar de un comando inmediato para actualizar el componente.

Porque piensan
Desde el enlace: https://github.com/facebook/react/issues/11527#issuecomment-360199710

... estamos de acuerdo en que la representación de setState () sincrónicamente sería ineficiente en muchos casos

AsSinchronous setState () hace que la vida sea muy difícil para aquellos que comienzan e incluso lamentablemente experimentan:
- problemas de representación inesperados: representación demorada o ausencia de representación (según la lógica del programa)
- pasar parámetros es un gran problema
entre otras cuestiones

El siguiente ejemplo ayudó:

// call doMyTask1 - here we set state // then after state is updated... // call to doMyTask2 to proceed further in program constructor(props) { // .. // This binding is necessary to make `this` work in the callback this.doMyTask1 = this.doMyTask1.bind(this); this.doMyTask2 = this.doMyTask2.bind(this); } function doMyTask1(myparam1) { // .. this.setState( { mystate1: ''myvalue1'', mystate2: ''myvalue2'' // ... }, () => { this.doMyTask2(myparam1); } ); } function doMyTask2(myparam2) { // .. }

Espero que ayude.