React-setState: ¿Cuál es el diseño de esta API?

1. Los puntos clave de setState:

  1. setState no cambia inmediatamente el valor del estado en los componentes React;
  2. setState desencadena un redibujo al desencadenar un proceso de actualización de componentes;
  3. Los efectos de múltiples llamadas a la función setState se fusionarán.

En segundo lugar, el uso simple del estado:

//读取状态
const count = this.state.count;

//更新状态
this.setState({count: count + 1});

//无意义
this.state.count = count + 1;

Debido a que this.state es solo un objeto al final, no tiene sentido simplemente modificar el valor de un objeto, tiene sentido impulsar la actualización de la interfaz de usuario. Piense en ello, si solo cambia el objeto de this.state, pero no permita Los componentes de reacción se vuelven a dibujar, ¿de qué sirve? Puede intentar modificar el valor de this.state directamente en el código, encontrará que puede cambiar el estado, pero no causará una nueva representación. 

Por lo tanto, debe usar una función para cambiar el estado. Esta función es setState. Cuando se llama a setState, puede impulsar el proceso de actualización del componente, lo que provoca una serie de llamadas a funciones, como componentDidUpdate y render.

Por supuesto, si usa la función de establecimiento de Object, en realidad puede lograr la misma función que setState modificando directamente este objeto.state, pero si React está realmente diseñado de esta manera, estoy seguro de que dicho diseño de API hará que Las personas están mareadas, porque no importa quién sea, no pueden ver a primera vista que modificar un objeto this.state realmente causará el efecto secundario de volver a renderizar.

De esta manera, React proporciona una API setState es una decisión muy razonable.

Debido a que setState no modifica inmediatamente el valor de this.state, el siguiente código puede producir resultados muy poco intuitivos.

function incrementMultiple() {
  this.setState({count: this.state.count + 1});
  this.setState({count: this.state.count + 1});
  this.setState({count: this.state.count + 1});
}

Intuitivamente, cuando se llama a la función incrementMultiple anterior, el valor de conteo del estado del componente aumenta 3 veces, cada vez aumenta en 1, luego el conteo finalmente aumenta en 3, pero el resultado real solo aumenta el estado en 1.

La razón no es complicada, porque cuando se llama this.setState, this.state no se cambia inmediatamente, por lo que this.setState simplemente establece repetidamente el mismo valor, el código anterior es equivalente al siguiente.

function incrementMultiple() {
  const currentCount = this.state.count;
  this.setState({count: currentCount + 1});
  this.setState({count: currentCount + 1});
  this.setState({count: currentCount + 1});
}

currentCount es un resultado de instantánea. Establezca repetidamente el mismo valor para contar, y mucho menos repita 3 veces, incluso si se repite 10,000 veces, el resultado solo aumentará en 1.

Dado que this.setState no modifica inmediatamente el valor de this.state, ¿cuándo debería modificarse el valor de this.state? Se trata del ciclo de vida de actualización de React.

setState desencadena un redibujo al desencadenar un proceso de actualización de componentes

Cuatro funciones de la función de actualización del ciclo de vida de React causada por la llamada setState (una función componenteWillReceiveProps menor que el ciclo de vida causado por la modificación de prop), estas cuatro funciones se llaman a su vez.

  • shouldComponentUpdate
  • componentWillUpdate
  • hacer
  • componentDidUpdate


Cuando se llama a la función shouldComponentUpdate, this.state no se actualiza.

Cuando se llama a la función componentWillUpdate, this.state todavía no se actualiza.

This.state no se actualiza hasta que se llama a la función de representación.

(O, cuando la función shouldComponentUpdate devuelve false, el proceso de actualización se interrumpirá y no se llamará a la función de renderizado. En este momento, React no abandonará la actualización de this.state, por lo que aunque el renderizado no se llama, seguirá siendo Actualice this.state.)

Si no está interesado en recordar el ciclo de vida de React (aunque debería recordarlo), simplemente puede pensar que no obtendrá el this.state actualizado hasta la próxima llamada a la función de renderizado (o la próxima vez que deberíaComponentUpdate devuelve falso).

Te guste o no, de todos modos this.state no se actualiza inmediatamente después de llamar a this.setState.

Los efectos de múltiples llamadas a la función setState se fusionarán

Por ejemplo, el siguiente código.

function updateName() {
  this.setState({FirstName: 'Morgan'});
  this.setState({LastName: 'Cheng'});
}

This.setState se llama dos veces seguidas, pero solo activará un ciclo de vida de actualización, no dos veces, porque React pondrá múltiples cambios realizados por this.setState en una cola, reducir la velocidad, guardar juntos, sentir casi El proceso de actualización se activa nuevamente.

En cada proceso de actualización, los resultados acumulados de setState se combinarán para realizar una acción de fusión, por lo que el código anterior es equivalente a esto.

function updateName() {
  this.setState({FirstName: 'Morgan', LastName: 'Cheng'});
}

Si cada this.setState desencadena un proceso de actualización, ¡es demasiado derrochador!

Para los desarrolladores, también puede llamar a this.setState varias veces, cada vez que solo necesita prestar atención al campo que está modificado actualmente, de todos modos, otros campos se fusionarán y retendrán, y no se pueden perder.

Por lo tanto, la decisión de diseño de la API de fusionar múltiples cambios a esta llamada this.setState no es mala.

En resumen, lo más regañador de setState es que no modificará este estado inmediatamente.

Si es posible, ¿cómo mejorar esta API?

En primer lugar, setState no debe actualizar esto inmediatamente. De lo contrario, todo el concepto de React se anulará, por lo que todo lo que puede hacer es expresarlo de una manera más clara, para que los desarrolladores no confundan this.state con la actualización de this.setState Parece que no hay una forma particularmente buena de mejorar.

Sin embargo, recientemente la función oculta de this.setState ha entrado en la visión de todos, es decir: ¡ resulta que this.setState puede aceptar una función como parámetro!

Esto es realmente un gran huevo en el mundo del juego React.

Uso funcional del estado

Si el parámetro pasado a this.setState no es un objeto sino una función, entonces las reglas del juego cambian.

 

Esta función recibirá dos parámetros, el primero es el valor del estado actual, el segundo son los accesorios actuales, esta función debe devolver un objeto, este objeto representa el cambio que desea realizar en este estado. En otras palabras, antes ¿Qué parámetro de objeto desea pasar a this.setState, qué objeto se devuelve en esta función? Sin embargo, el método de cálculo de este objeto ha cambiado algo, ya no depende de this.state, sino que depende del estado del parámetro de entrada.

Por ejemplo, para el ejemplo anterior de agregar conteo al estado, puede escribir una función como esta.

function increment(state, props) {
  return {count: state.count + 1};
}

Se puede ver que la cuenta en el estado también aumenta en 1, pero la fuente del estado no es this.state, sino el estado del parámetro de entrada.

Esta es la función para incrementMultiple.

function incrementMultiple() {
  this.setState(increment);
  this.setState(increment);
  this.setState(increment);
}

En el caso de múltiples llamadas al setState funcional, React se asegurará de que cada vez que se llame al incremento, el estado haya fusionado los resultados de modificación de estado anteriores.

En pocas palabras, el valor actual de this.state.count es 0, la primera llamada a this.setState (incremento), el parámetro de estado pasado al incremento es 0, cuando la segunda llamada, el parámetro de estado es 1, la tercera llamada es , El parámetro es 2, y finalmente el efecto de incrementMultiple realmente hace que this.state.count se convierta en 3, y esta función incrementMultiple finalmente se merece.

Vale la pena mencionar que cuando se llama a la función de incremento, this.state no se ha cambiado, pero no cambiará hasta que se vuelva a ejecutar la función de renderizado (o después de que la función shouldComponentUpdate devuelva false).

¡El diseño de la API para permitir que setState acepte una función es excelente! Debido a que esto se ajusta a la idea de la programación funcional, deje que los desarrolladores escriban funciones sin efectos secundarios. Nuestra función de incremento no modifica el estado del componente, sino que simplemente devuelve el "cambio de estado deseado" a React, y el arduo trabajo de mantener el estado se entrega por completo Reaccionar para hacerlo.

Debido a que el control del proceso se le da a React, React puede coordinar la relación entre múltiples llamadas setState.

Vamos un paso más allá e intentemos mezclar los dos usos de setState, ¿qué efecto tendrá?

Cambiamos el incremento Múltiple a esto.

function incrementMultiple() {
  this.setState(increment);
  this.setState(increment);
  this.setState({count: this.state.count + 1});
  this.setState(increment);
}

Inserte una llamada setState tradicional en varias llamadas setState funcionales (bueno, llamemos al uso setState anterior), y el resultado final es aumentar this.state.count en 2 en lugar de en 4.

La razón también es muy simple, porque React fusionará todos los efectos de setState en secuencia. Aunque el efecto de las dos primeras llamadas setState es cuenta más 2, una llamada setState tradicional se elimina a la mitad, y el efecto acumulado se elimina de inmediato. , Reemplace con cuenta más 1.

¡De esta manera, la existencia del setState tradicional arrastrará el setState funcional al agua! Mientras haya una llamada setState tradicional, perjudica a otras llamadas setState funcionales.

Si la API de setState se mejora en el futuro, quizás el método de llamada con función como parámetro debería adoptarse por completo, y el método de llamada con objeto como parámetro debería abolirse.

Por supuesto, React ciertamente no tendrá un cambio tan sorprendente en el futuro cercano, pero primero puede probar el uso de setState funcional, que es el futuro de setState.

Publicado 35 artículos originales · ganado elogios 1 · vistas 6718

Supongo que te gusta

Origin blog.csdn.net/qq_36162529/article/details/101209597
Recomendado
Clasificación