Stellen Sie sich vor, Sie erhöhen einen Zähler in einer Komponente:
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>
...
)
}
}
Sowohl der übergeordneten als auch der untergeordneten Komponente ist ein Zählhandler zugeordnet. Dies geschieht absichtlich, damit wir setState () zweimal im selben Kontext für das Sprudeln von Klickereignissen ausführen können, jedoch innerhalb von zwei verschiedenen Handlern.
Wie wir uns vorstellen würden, würde ein Ereignis mit einem Klick auf die Schaltfläche nun beide Handler auslösen, da das Ereignis während der Blasenphase vom Ziel zum äußersten Container sprudelt.
Daher wird btnCountHandler () zuerst ausgeführt, wobei erwartet wird, dass die Anzahl auf 1 erhöht wird, und dann wird divCountHandler () ausgeführt, um die Anzahl auf 2 zu erhöhen.
Die Anzahl wird jedoch nur auf 1 erhöht, wie Sie in den React Developer-Tools überprüfen können.
Dies beweist, dass reagieren
stellt alle setState-Aufrufe in die Warteschlange
kehrt zu dieser Warteschlange zurück, nachdem die letzte Methode im Kontext ausgeführt wurde (in diesem Fall der divCountHandler).
führt alle Objektmutationen, die innerhalb mehrerer setState-Aufrufe im selben Kontext auftreten (z. B. alle Methodenaufrufe innerhalb einer einzelnen Ereignisphase, zum selben Kontext), zu einer einzigen Objektmutationssyntax zusammen (Zusammenführung ist sinnvoll, da wir daher die Statuseigenschaften unabhängig voneinander aktualisieren können in setState () an erster Stelle)
und übergibt es an ein einzelnes setState (), um ein erneutes Rendern aufgrund mehrerer setState () -Aufrufe zu verhindern (dies ist eine sehr primitive Beschreibung der Stapelverarbeitung).
Resultierender Code, der von react ausgeführt wird:
this.setState({
updatedByDiv: 'Div',
updatedByBtn: 'Button',
counter: this.state.counter + 1
})
Um dieses Verhalten zu stoppen, werden Rückrufe übergeben, anstatt Objekte als Argumente an die setState-Methode zu übergeben.
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');
}
Nachdem die letzte Methode die Ausführung abgeschlossen hat und reag zurückkehrt, um die setState-Warteschlange zu verarbeiten, ruft sie einfach den Rückruf für jede setState-Warteschlange auf und übergibt den vorherigen Komponentenstatus.
Auf diese Weise wird sichergestellt, dass der letzte Rückruf in der Warteschlange den Status aktualisiert, den alle vorherigen Kollegen in die Hand genommen haben.