reactjs - receive - react setstate function
Cuándo usar React setState callback (4)
Cuando cambia el estado de un componente de reacción, se llama al método de representación. Por lo tanto, para cualquier cambio de estado, se puede realizar una acción en el cuerpo de los métodos de representación. ¿Hay un caso de uso particular para la devolución de llamada setState entonces?
1. El caso de uso que me viene a la mente, es una llamada a la
api
, que no debe entrar en el render, porque se ejecutará para
each
cambio de estado.
Y la llamada a la API solo debe realizarse en un cambio de estado especial, y no en
cada
render.
changeSearchParams = (params) => {
this.setState({ params }, this.performSearch)
}
performSearch = () => {
API.search(this.state.params, (result) => {
this.setState({ result })
});
}
Por lo tanto, para cualquier cambio de estado, se puede realizar una acción en el cuerpo de los métodos de representación.
Muy mala práctica
, ya que el método de
render
debe ser puro, significa que no se deben realizar acciones, cambios de estado, llamadas a la API, solo componga su vista y devuélvala.
Las acciones deben realizarse solo en algunos eventos.
Renderizar no es un evento, sino
componentDidMount
por ejemplo.
Considere la llamada setState
this.setState({ counter: this.state.counter + 1 })
IDEA 1
Se puede llamar a setState en función asincrónica
Entonces no puedes confiar en
this
.
Si la llamada anterior se realizó dentro de una función asíncrona,
this
se referirá al estado del componente en ese punto de tiempo, pero esperábamos que esto se refiriera al estado interno de la propiedad en la llamada setState del tiempo o al comienzo de la tarea asincrónica.
Y como la tarea era llamada asincrónica, esa propiedad puede haber cambiado con el tiempo.
Por lo tanto, no es confiable usar
this
palabra clave para referirse a alguna propiedad de estado, por lo tanto, usamos la función de devolución de llamada cuyos argumentos son anteriorState y props, lo que significa que cuando se realizó la tarea asincrónica y que era hora de actualizar el estado usando setState, la llamada anteriorState se referirá al estado ahora cuando setState aún no ha comenzado.
Garantizar la fiabilidad de que nextState no se corromperá.
Código incorrecto: conduciría a la corrupción de datos
this.setState(
{counter:this.state.counter+1}
);
Código correcto con setState con función de devolución de llamada:
this.setState(
(prevState,props)=>{
return {counter:prevState.counter+1};
}
);
Por lo tanto, cada vez que necesitemos actualizar nuestro estado actual al siguiente estado en función del valor presentado por la propiedad en este momento y todo esto está sucediendo de manera asíncrona, es una buena idea usar setState como función de devolución de llamada.
IDEA 2
La llamada setState puede ser
async
sí misma bcz
React
puede intentar combinar dos o más llamadas setState juntas para mejorar el
rendimiento
.
De todos modos eso no es confiable
.
Supongamos que dos llamadas setState se disparan en
t = 0
.
Ambos se referían al mismo estado
(estado_0)
antes de la llamada, siendo asíncronos no podemos confiar en cuál terminará primero.
Supongamos que una llamada puede conducir al
estado_1
cuando uno de ellos finaliza.
Y otra llamada donde state se refería al estado inicial
(state_0)
puede conducir a
state_3
.
Y esto puede conducir a la corrupción de los estados y sus datos.
Usar una devolución de llamada donde los argumentos para la función de devolución de llamada es prevState, props.
Se asegura de que si uno de ellos termina primero en
estado_1
, el siguiente setState siempre se referirá a prevState como estado inicial.
Por lo tanto, asegúrese siempre de que los datos no se corrompan.
Es muy poco probable que los datos se dañen de esta manera debido a que se llama a setState simultáneamente.
Pero si se requiere que nuestro próximo estado dependa de prevState, use siempre la devolución de llamada.
He tratado de explicarlo en codepen aquí CODE PEN
Sí, ya que
setState
funciona de forma
asynchronous
.
Eso significa que después de llamar a
setState
la variable
this.state
no cambia inmediatamente.
así que si desea realizar una acción inmediatamente después de establecer el estado en una variable de estado y luego devolver un resultado, una devolución de llamada será útil
Considere el siguiente ejemplo
....
changeTitle: function changeTitle (event) {
this.setState({ title: event.target.value });
this.validateTitle();
},
validateTitle: function validateTitle () {
if (this.state.title.length === 0) {
this.setState({ titleError: "Title can''t be blank" });
}
},
....
Es posible que el código anterior no funcione como se esperaba, ya que la variable de
title
puede no haber mutado antes de que se realice la validación.
Ahora puede preguntarse si podemos realizar la validación en la función
render()
, pero sería mejor y más limpio si podemos manejar esto en la función changeTitle, ya que eso haría que su código sea más organizado y comprensible
En este caso, la devolución de llamada es útil
....
changeTitle: function changeTitle (event) {
this.setState({ title: event.target.value }, function() {
this.validateTitle();
});
},
validateTitle: function validateTitle () {
if (this.state.title.length === 0) {
this.setState({ titleError: "Title can''t be blank" });
}
},
....
Otro ejemplo será cuando desee
dispatch
y actuar cuando el estado cambió.
querrá hacerlo en una devolución de llamada y no en el
render()
ya que se llamará cada vez que se produzca la devolución y, por lo tanto, es posible que haya muchos de esos escenarios en los que necesitará la devolución de llamada.
Otro caso es una
API Call
Puede surgir un caso cuando necesite hacer una llamada a la API en función de un cambio de estado particular, si lo hace en el método de representación, se
onState
en cada cambio de representación en el
onState
o porque alguna Prop transmitida al
Child Component
onState
cambió.
En este caso, desearía utilizar una
setState callback
de
setState callback
para pasar el valor de estado actualizado a la llamada API
....
changeTitle: function (event) {
this.setState({ title: event.target.value }, () => this.APICallFunction());
},
APICallFunction: function () {
// Call API with the updated value
}
....
this.setState({
name:''value''
},() => {
console.log(this.state.name);
});