Apa cara yang benar untuk menggunakan InheritedWidget? Sejauh ini saya mengerti bahwa ini memberi Anda kesempatan untuk menyebarkan data ke pohon Widget. Secara ekstrim jika Anda meletakkannya sebagai RootWidget, itu akan dapat diakses dari semua Widget di pohon di semua Rute, yang tidak masalah karena entah bagaimana saya harus membuat ViewModel / Model saya dapat diakses untuk Widget saya tanpa harus menggunakan global atau Singletons.
TAPI InheritedWidget tidak dapat diubah, jadi bagaimana cara memperbaruinya? Dan yang lebih penting bagaimana Stateful Widgets saya dipicu untuk membangun kembali subpohonnya?
Sayangnya dokumentasinya ada di sini sangat tidak jelas dan setelah diskusi dengan banyak orang sepertinya tidak ada yang benar-benar tahu apa cara yang benar untuk menggunakannya.
Saya menambahkan kutipan dari Brian Egan:
Ya, saya melihatnya sebagai cara untuk menyebarkan data ke bawah pohon. Yang menurut saya membingungkan, dari dokumen API:
"Widget yang diwariskan, jika direferensikan dengan cara ini, akan menyebabkan konsumen membuat ulang saat widget yang diwariskan itu sendiri berubah status."
Ketika saya pertama kali membaca ini, saya berpikir:
Saya bisa memasukkan beberapa data di InheritedWidget dan memutasinya nanti. Ketika mutasi itu terjadi, itu akan membangun kembali semua Widget yang mereferensikan InheritedWidget saya Apa yang saya temukan:
Untuk memutasi State of an InheritedWidget, Anda perlu membungkusnya dalam StatefulWidget. Anda kemudian benar-benar mengubah status StatefulWidget dan meneruskan data ini ke InheritedWidget, yang menyerahkan data ke semua turunannya. Namun, dalam kasus ini, tampaknya membangun kembali seluruh pohon di bawah StatefulWidget, bukan hanya Widget yang mereferensikan InheritedWidget. Apakah itu benar? Atau apakah itu akan tahu cara melewati Widget yang mereferensikan InheritedWidget jika updateShouldNotify mengembalikan false?
sumber
MyInherited.of(context)
.updateShouldNotify
pengujian selalu mengacu padaMyInheritedState
contoh yang sama , bukankah akan selalu kembalifalse
? Tentu sajabuild
metodeMyInheritedState
membuat_MyInherited
instance baru , tetapi kolomdata
selalu merujukthis
no? Saya mengalami masalah ... Berfungsi jika saya hanya membuat kode kerastrue
.TL; DR
Jangan gunakan komputasi berat di dalam metode updateShouldNotify dan gunakan const sebagai ganti yang baru saat membuat widget
Pertama-tama, kita harus memahami apa itu widget, Element, dan objek Render.
Sekarang kita siap untuk menyelami metode InheritedWidget dan BuildContext inheritFromWidgetOfExactType .
Sebagai contoh, saya sarankan kami mempertimbangkan contoh ini dari dokumentasi Flutter tentang InheritedWidget:
InheritedWidget - hanya sebuah widget yang diimplementasikan dalam kasus kami satu metode penting - updateShouldNotify . updateShouldNotify - fungsi yang menerima satu parameter oldWidget dan mengembalikan nilai boolean: true atau false.
Seperti widget lainnya, InheritedWidget memiliki objek Elemen yang sesuai. Itu adalah InheritedElement . Panggilan InheritedElement updateShouldNotify pada widget setiap kali kita membuat widget baru (panggil setState pada leluhur). Ketika updateShouldNotify mengembalikan True InheritedElement melakukan iterasi melalui dependensi (?) Dan memanggil metode didChangeDependencies padanya.
Di mana InheritedElement mendapatkan dependensi ? Di sini kita harus melihat metode inheritFromWidgetOfExactType .
inheritFromWidgetOfExactType - Metode ini ditentukan dalam BuildContext dan setiap Elemen mengimplementasikan antarmuka BuildContext (Element == BuildContext). Jadi setiap Elemen memiliki metode ini.
Mari kita lihat kode inheritFromWidgetOfExactType:
Di sini kami mencoba menemukan leluhur di _inheritedWidgets yang dipetakan berdasarkan jenis. Jika leluhur ditemukan, kita kemudian memanggil inheritFromElement .
Kode untuk inheritFromElement :
Jadi sekarang kita tahu dari mana InheritedElement mendapatkan dependensinya.
Sekarang mari kita lihat metode didChangeDependencies . Setiap Elemen memiliki metode ini:
Seperti yang kita lihat, metode ini hanya menandai elemen sebagai kotor dan elemen ini harus dibangun kembali pada bingkai berikutnya. Rebuild berarti metode panggilan yang dibangun di atas elemen widget yang sesuai.
Tapi bagaimana dengan "Seluruh sub-pohon membangun kembali ketika saya membangun kembali InheritedWidget?". Di sini kita harus ingat bahwa Widget tidak dapat diubah dan jika Anda membuat widget baru Flutter akan membangun kembali sub-pohon. Bagaimana cara memperbaikinya?
sumber
Dari dokumen :
Seperti yang dicatat OP, sebuah
InheritedWidget
instance tidak berubah ... tetapi dapat diganti dengan instance baru di lokasi yang sama di pohon widget. Jika itu terjadi, mungkin saja widget yang terdaftar perlu dibangun kembali. TheInheritedWidget.updateShouldNotify
Metode membuat penentuan ini. (Lihat: dokumen )Jadi bagaimana sebuah contoh bisa diganti? Sebuah
InheritedWidget
contoh mungkin berisi olehStatefulWidget
, yang dapat menggantikan contoh lama dengan yang baru.sumber
InheritedWidget mengelola data aplikasi yang terpusat dan meneruskannya ke anak, Seperti yang bisa kita simpan di sini jumlah keranjang seperti yang dijelaskan di sini :
sumber