Saya mengerjakan React.
TLDR:
Tapi bisakah Anda percaya Bereaksi untuk memperbarui keadaan dalam urutan yang sama seperti setState dipanggil untuk
Iya.
Iya.
The rangka update selalu dihormati. Apakah Anda melihat kondisi antara "di antara" mereka atau tidak tergantung pada apakah Anda berada di dalam kumpulan atau tidak.
Saat ini (Bereaksi 16 dan sebelumnya), hanya pembaruan di dalam penangan aktivitas Bereaksi yang di-batch secara default . Ada API yang tidak stabil untuk memaksa batching di luar event handler untuk kasus yang jarang terjadi saat Anda membutuhkannya.
Dalam versi yang akan datang (mungkin Bereaksi 17 dan yang lebih baru), Bereaksi akan mengelompokkan semua pembaruan secara default sehingga Anda tidak perlu memikirkan hal ini. Seperti biasa, kami akan mengumumkan perubahan apa pun tentang ini di blog Bereaksi dan dalam catatan rilis.
Kunci untuk memahami ini adalah bahwa tidak peduli berapa banyak setState()
panggilan dalam berapa banyak komponen yang Anda lakukan di dalam penangan peristiwa Bereaksi , mereka hanya akan menghasilkan render tunggal pada akhir acara . Ini sangat penting untuk kinerja yang baik dalam aplikasi besar karena jika Child
dan Parent
setiap panggilan setState()
saat menangani acara klik, Anda tidak ingin merender ulang Child
dua kali.
Dalam kedua contoh Anda, setState()
panggilan terjadi di dalam pengendali event Bereaksi. Oleh karena itu mereka selalu memerah bersama di akhir acara (dan Anda tidak melihat negara perantara).
Pembaruan selalu dangkal digabung dalam urutan terjadinya . Jadi, jika pembaruan pertama adalah {a: 10}
, yang kedua adalah {b: 20}
, dan yang ketiga adalah {a: 30}
, keadaan yang diberikan akan {a: 30, b: 20}
. Pembaruan yang lebih baru untuk kunci negara yang sama (misalnya seperti a
dalam contoh saya) selalu "menang".
The this.state
objek diperbarui ketika kita kembali membuat UI pada akhir bets. Jadi, jika Anda perlu memperbarui negara berdasarkan keadaan sebelumnya (seperti menambah penghitung), Anda harus menggunakan setState(fn)
versi fungsional yang memberi Anda keadaan sebelumnya, alih-alih membaca dari this.state
. Jika Anda penasaran dengan alasan untuk ini, saya jelaskan secara mendalam dalam komentar ini .
Dalam contoh Anda, kami tidak akan melihat "keadaan perantara" karena kami berada di dalam penangan peristiwa Bereaksi tempat batching diaktifkan (karena Bereaksi "tahu" ketika kita keluar dari peristiwa itu).
Namun, baik dalam Bereaksi 16 dan versi sebelumnya, belum ada batching secara default di luar penangan event Bereaksi . Jadi, jika dalam contoh Anda, kami memiliki penangan respons AJAX alih-alih handleClick
, masing setState()
- masing akan segera diproses begitu terjadi. Dalam hal ini, ya, Anda akan melihat kondisi perantara:
promise.then(() => {
// We're not in an event handler, so these are flushed separately.
this.setState({a: true}); // Re-renders with {a: true, b: false }
this.setState({b: true}); // Re-renders with {a: true, b: true }
this.props.setParentState(); // Re-renders the parent
});
Kami menyadari tidak nyaman bahwa perilakunya berbeda tergantung pada apakah Anda berada dalam event handler atau tidak . Ini akan berubah di versi Bereaksi masa depan yang akan mengelompokkan semua pembaruan secara default (dan menyediakan API keikutsertaan untuk menyiram perubahan secara sinkron). Sampai kami beralih perilaku default (berpotensi dalam Bereaksi 17), ada API yang dapat Anda gunakan untuk memaksa batching :
promise.then(() => {
// Forces batching
ReactDOM.unstable_batchedUpdates(() => {
this.setState({a: true}); // Doesn't re-render yet
this.setState({b: true}); // Doesn't re-render yet
this.props.setParentState(); // Doesn't re-render yet
});
// When we exit unstable_batchedUpdates, re-renders once
});
React event handler internal semuanya dibungkus unstable_batchedUpdates
dan itulah sebabnya mereka dikelompokkan secara default. Perhatikan bahwa membungkus pembaruan unstable_batchedUpdates
dua kali tidak berpengaruh. Pembaruan memerah ketika kita keluar dari unstable_batchedUpdates
panggilan terluar .
API itu "tidak stabil" dalam arti bahwa kami akan menghapusnya ketika batching sudah diaktifkan secara default. Namun, kami tidak akan menghapusnya dalam versi kecil, sehingga Anda dapat dengan aman mengandalkannya sampai Bereaksi 17 jika Anda perlu memaksa batching dalam beberapa kasus di luar React event handler.
Singkatnya, ini adalah topik yang membingungkan karena Bereaksi hanya kumpulan di dalam penangan acara secara default. Ini akan berubah di versi masa depan, dan perilaku akan lebih mudah. Tapi solusinya bukan batch lebih sedikit , itu untuk batch lebih banyak secara default. Itu yang akan kita lakukan.