Bayangkan menambah penghitung di beberapa komponen:
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>
...
)
}
}
Ada penangan hitungan yang dipasang ke komponen induk dan anak. Ini dilakukan dengan sengaja sehingga kita bisa mengeksekusi setState () dua kali dalam konteks gelembung peristiwa klik yang sama, tetapi dari dalam 2 penangan yang berbeda.
Seperti yang dapat kita bayangkan, satu peristiwa klik pada tombol sekarang akan memicu kedua penangan ini karena peristiwa menggelembung dari target ke wadah terluar selama fase menggelegak.
Oleh karena itu, btnCountHandler () dieksekusi terlebih dahulu, diharapkan menaikkan hitungan menjadi 1 dan kemudian divCountHandler () dieksekusi, diharapkan menambah hitungan menjadi 2.
Namun hitungannya hanya bertambah menjadi 1 karena Anda dapat memeriksa di alat Pengembang React.
Ini membuktikan bahwa bereaksi
mengantri semua panggilan setState
kembali ke antrian ini setelah menjalankan metode terakhir dalam konteks (divCountHandler dalam kasus ini)
menggabungkan semua mutasi objek yang terjadi dalam beberapa panggilan setState dalam konteks yang sama (semua panggilan metode dalam satu fase peristiwa adalah konteks yang sama misalnya) menjadi satu sintaks mutasi objek (penggabungan masuk akal karena inilah mengapa kita dapat memperbarui properti status secara independen di setState () di tempat pertama)
dan meneruskannya ke dalam satu setState () untuk mencegah rendering ulang karena beberapa panggilan setState () (ini adalah deskripsi batching yang sangat primitif).
Kode yang dihasilkan dijalankan oleh react:
this.setState({
updatedByDiv: 'Div',
updatedByBtn: 'Button',
counter: this.state.counter + 1
})
Untuk menghentikan perilaku ini, alih-alih meneruskan objek sebagai argumen ke metode setState, callback akan diteruskan.
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');
}
Setelah metode terakhir menyelesaikan eksekusi dan saat react kembali untuk memproses antrian setState, itu hanya memanggil callback untuk setiap setState yang antri, meneruskan status komponen sebelumnya.
Reaksi cara ini memastikan bahwa callback terakhir dalam antrean akan memperbarui status yang telah dilakukan oleh semua mitra sebelumnya.