Red de conocimientos turísticos - Información de alquiler - ¿A qué debes prestar atención al usar React.setState?

¿A qué debes prestar atención al usar React.setState?

Este artículo presenta principalmente tres puntos a los que se debe prestar atención al usar React.setState. Presenta tres puntos que son fáciles de ignorar para los principiantes en React. Tiene cierto valor de referencia y es de interés. Amigos, pueden consultarlo

Prólogo

El título original de este artículo es 3 razones por las que dejé de usar React.setState, pero no estoy muy interesado en los argumentos presentados. Por el autor original, pero los tres puntos planteados por el autor son fáciles de ignorar para los principiantes en React, por lo que solo mencionaré parte del contenido aquí y cambiaré el título a tres puntos a los que se debe prestar atención al usar React. establecer estado.

Texto

Para los principiantes en React, usar setState es algo muy complicado. Incluso aquellos que tienen experiencia en el desarrollo de React probablemente tendrán algunos errores debido a algunos mecanismos de React, como el siguiente ejemplo:

El documento también explica a qué problemas se debe prestar atención al usar setState:

Nota:

Nunca cambie this.state directamente, porque llamar a setState() más tarde puede reemplazar sus cambios

. Trate este estado como inmutable.

setState() no cambia this.state inmediatamente, pero crea una transición de estado que se procesará pronto. Acceder a this.state después de llamar a este método puede devolver el valor existente.

No hay garantías de sincronización para las llamadas a setState y las llamadas pueden agruparse por lotes para mejorar el rendimiento.

setState() siempre activará un redibujado a menos que se implemente una lógica de representación condicional en shouldComponentUpdate(). Si se utilizan objetos mutables y esta lógica no se puede implementar en shouldComponentUpdate(), llamar a setState() solo cuando hay una diferencia entre el nuevo estado y el estado anterior puede evitar una repetición innecesaria.

En resumen, hay tres cuestiones a las que se debe prestar atención al utilizar setState:

1. setState es asincrónico (Nota del traductor: la sincronización no está garantizada)

Muchos desarrolladores no notaron que setState es asíncrono al principio. Si modifica algún estado y luego lo ve directamente, verá el estado anterior. Este es el lugar más propenso a errores en setState. La palabra setState no parece asincrónica, por lo que puede causar errores si la usas sin pensar.

El siguiente ejemplo ilustra bien este problema:

class Select extends React.Component {

constructor(props, context) {

super(props, context)

this.state = {

selección: props.values[0]

};

}

render() {

return (

    {this.props.values.map (valor =>

    className={valor === this.state.selection ? 'seleccionado' : ''}

    clave={ valor}

    onClick={() => this.onSelect(valor)}

    {valor}

    )}

)

}

onSelect( valor) {

this.setState({

selección: valor

})

this.fireOnSelect()

}

onKeyDown = (e) => {

const {valores} = this.props

const idx = valores.indexOf(this. state.selection )

if (e.keyCode === 38 && idx > 0) { /* up */

this.setState({

selección: valores [idx - 1]

})

} else if (e.keyCode === 40 && idx

this.setState({

selección: valores[idx + 1]

})

}

this. fireOnSelect()

}

fireOnSelect() {

if (tipo de this.props.onSelect === "función")

this.props.onSelect(this.state.selection) /* no es lo que esperabas..*/

}

}

ReactDOM .render(

valores={["Estado.", "Debería.", "Ser.", "Sincrónico."]}

onSelect= {valor => console.log(valor)}

/>,

documento

ment.getElementById("app")

) A primera vista, no parece haber nada malo en este código. El método onSelect se llama en ambos controladores de eventos. Sin embargo, hay un error en este componente Seleccionar que ilustra muy bien el GIF anterior. El método onSelect siempre pasa el valor state.selection anterior, porque cuando se llama a fireOnSelect, setState aún no ha completado su trabajo. Creo que React debería al menos cambiar setState a ScheduleState o hacer que la función de devolución de llamada sea un parámetro obligatorio.

Este error es fácil de solucionar. La parte más difícil es saber que hay un problema.

2. setState provocará una renderización innecesaria

El segundo problema causado por setState es que cada llamada provocará una nueva renderización. Muchas veces, estas rerenderizaciones son innecesarias. Puede utilizar printWasted en las herramientas de rendimiento de React para ver cuándo se produce una representación innecesaria. Sin embargo, en términos generales, existen varias razones para la representación innecesaria:

El nuevo estado es en realidad el mismo que el anterior. Este problema normalmente se puede resolver con mustComponentUpdate. También puedes usar renderizado puro u otras bibliotecas para resolver este problema.

Normalmente el estado cambiado está relacionado con el renderizado, pero hay excepciones. Por ejemplo, algunos datos se muestran en función de determinados estados.

En tercer lugar, algún estado no tiene nada que ver con la renderización. Algún estado puede estar relacionado con eventos e ID de temporizador.

3.setState no puede administrar eficazmente todos los estados de los componentes

Según el último punto anterior, no todos los estados de los componentes deben guardarse y actualizarse con setState. Los componentes complejos pueden tener una variedad de estados que deben gestionarse. El uso de setState para administrar estos estados no solo provocará una gran cantidad de renderizaciones innecesarias, sino que también provocará que se llamen enlaces de ciclo de vida relacionados todo el tiempo, lo que provocará muchos problemas extraños.

Epílogo

En el artículo original, el autor recomendó una biblioteca llamada MobX para administrar algunos estados. No soy muy frío, así que no la presentaré. Si está interesado, puede leer la introducción en el artículo original a través del enlace en la parte superior.

Basándonos en los tres puntos planteados anteriormente, creo que los novatos deberían prestar atención a lo siguiente:

setState no garantiza la sincronización

setState no garantiza la sincronización. La sincronización no está garantizada, la sincronización no está garantizada. Di cosas importantes tres veces. La razón por la que no se dice que sea asincrónico es porque setState también se actualiza sincrónicamente en algunos casos. Puede consultar este artículo

Si necesita obtener el valor modificado directamente después de setState, hay varias opciones:

Pasar los parámetros correspondientes y no obtenerlos a través de esto. state

Para el ejemplo anterior, puede pasar el valor requerido al llamar a fireOnSelect. En lugar de obtenerlo a través de this.state en el método

Usa una función de devolución de llamada

El método setState recibe una función como una función de devolución de llamada. Esta función de devolución de llamada se llamará directamente después de que se complete setState, para que se pueda obtener el último estado. Para el ejemplo anterior, esto sería:

this.setState({

selección: valor

}, this.fireOnSelect) usando setTimeout

Utilice setTimeout en setState para permitir que setState se complete primero y luego ejecute el contenido interno.

Así:

this.setState({

selección: valor

});

setTimeout(this.fireOnSelect, 0) ;Salida directa, función de devolución de llamada, comparación setTimeout

componentDidMount(){

this.setState({val: this.state.val + 1}, ()=>{

console.log("En devolución de llamada " + this.state.val);

});

console.log("Llamada directa " + this.state .val);

setTimeout(()=>{

console.log("comienzo de setTimeout" + this.state.val);

this .setState({val: this.state.val + 1}, ()=>{

console.log("setTimeout setState callback " + this.state.val);

});

setTimeout(()=>{

console.log("setTimeout de settimeout " + this.state.val);

} , 0);

console.log("fin de setTimeout " + this.state.val);

}, 0);

}Si val El valor predeterminado es 0, el resultado de la entrada es:

Llamada directa 0

En devolución de llamada 1

comienzo de setTimeout 1

setTimeout setState callback 2

fin de setTimeout 2

setTimeout de settimeout 2

Intenta no gestionar estados que no tengan nada que ver con el renderizado en estado

Por lo general, en el estado solo se administra el estado relacionado con la representación, lo que garantiza que el estado cambiado por setState sea todo el estado relacionado con la representación. De esta manera puede evitar representaciones repetidas innecesarias. Otros estados que no tienen nada que ver con la representación se pueden guardar directamente en el componente en forma de atributos y se pueden llamar y cambiar cuando sea necesario sin provocar la representación.

Evita modificaciones innecesarias. Cuando el valor de state no haya cambiado, intenta no utilizar setState. Aunque deberíaComponentUpdate y PureComponent pueden evitar la renderización repetida innecesaria, aún agregan una capa de llamadas superficiales a Equal, lo que provoca un desperdicio innecesario.

Lo anterior es lo que compilé para todos. Espero que sea útil para todos en el futuro.

Artículos relacionados:

Usar axios para cargar archivos en vue

Cómo usar gulp para crear un proceso de proyecto completo

En js Cómo agregar una matriz a un objeto

Cómo controlar dinámicamente los elementos de la página en jQuery

Cómo implementar la función de reproducción de pistas en el lienzo