Karena berbagai alasan, terkadang build
metode widget saya dipanggil lagi.
Saya tahu itu terjadi karena orang tua diperbarui. Tetapi ini menyebabkan efek yang tidak diinginkan. Situasi umum yang menyebabkan masalah adalah saat menggunakan FutureBuilder
cara ini:
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: httpCall(),
builder: (context, snapshot) {
// create some layout here
},
);
}
Dalam contoh ini, jika metode build dipanggil lagi, itu akan memicu permintaan http lain. Yang tidak diinginkan.
Mempertimbangkan hal ini, bagaimana cara menangani bangunan yang tidak diinginkan? Apakah ada cara untuk mencegah panggilan membangun?
flutter
flutter-widget
Rémi Rousselet
sumber
sumber
Jawaban:
The build Metode ini dirancang sedemikian rupa bahwa itu harus murni / tanpa efek samping . Ini karena banyak faktor eksternal dapat memicu pembangunan widget baru, seperti:
Class.of(context)
perubahan ( pola)Ini berarti bahwa
build
metode ini tidak boleh memicu panggilan http atau memodifikasi keadaan apa pun .Bagaimana ini terkait dengan pertanyaan?
Masalah yang Anda hadapi adalah bahwa metode build Anda memiliki efek samping / tidak murni, membuat panggilan build tambahan merepotkan.
Alih-alih mencegah panggilan build, Anda harus membuat metode build Anda murni, sehingga dapat dipanggil kapan saja tanpa dampak.
Dalam kasus contoh Anda, Anda akan mengubah widget Anda menjadi
StatefulWidget
kemudian ekstrak bahwa panggilan HTTP keinitState
dari AndaState
:Dimungkinkan juga untuk membuat widget yang mampu membangun kembali tanpa memaksa anak-anaknya untuk membangun juga.
Ketika instance widget tetap sama; Flutter dengan sengaja tidak akan membangun kembali anak-anak. Ini menyiratkan bahwa Anda dapat melakukan cache bagian pohon widget Anda untuk mencegah pembangunan kembali yang tidak perlu.
Cara termudah adalah dengan menggunakan
const
konstruktor panah :Berkat
const
kata kunci itu, instance dariDecoratedBox
akan tetap sama meskipun build disebut ratusan kali.Tetapi Anda dapat mencapai hasil yang sama secara manual:
Dalam contoh ini ketika StreamBuilder diberitahu tentang nilai-nilai baru,
subtree
tidak akan membangun kembali bahkan jika StreamBuilder / Kolom melakukannya. Itu terjadi karena, berkat penutupan, contohMyWidget
tidak berubah.Pola ini banyak digunakan dalam animasi. Kegunaan umum adalah
AnimatedBuilder
dan semua transisi sepertiAlignTransition
.Anda juga dapat menyimpan
subtree
ke bidang kelas Anda, meskipun kurang direkomendasikan karena merusak fitur hot-reload.sumber
subtree
di bidang kelas memecah hot-reload?StreamBuilder
adalah ketika keyboard muncul layar berubah, sehingga rute harus dibangun kembali. JadiStreamBuilder
dibangun kembali dan yang baruStreamBuilder
dibuat dan berlanggananstream
. KetikaStreamBuilder
berlanggananstream
,snapshot.connectionState
menjadiConnectionState.waiting
yang membuat kode saya kembaliCircularProgressIndicator
, dan kemudiansnapshot.connectionState
berubah ketika ada data, dan kode saya akan mengembalikan widget yang berbeda, yang membuat layar berkedip dengan hal-hal yang berbeda.StatefulWidget
, berlanggananstream
padainitState()
dan mengaturcurrentWidget
dengansetState()
sebagaistream
mengirimkan data baru, melewaticurrentWidget
kebuild()
metode. Apakah ada solusi yang lebih baik?FutureBuilder
.Anda dapat mencegah panggilan membangun yang tidak diinginkan, menggunakan cara ini
1) Buat kelas Statefull anak untuk setiap bagian kecil UI
2) Gunakan perpustakaan Provider , jadi menggunakannya Anda dapat menghentikan pemanggilan metode build yang tidak diinginkan.
Dalam pemanggilan metode build situasi berikut ini
sumber
Flutter juga punya
ValueListenableBuilder<T> class
. Ini memungkinkan Anda untuk membangun kembali hanya beberapa widget yang diperlukan untuk tujuan Anda dan melewatkan widget mahal.Anda dapat melihat dokumen-dokumen di sini ValueListenableBuilder bergetar dokumen
atau hanya kode sampel di bawah ini:
sumber