Saya telah menyadari bahwa dimungkinkan untuk membuat widget menggunakan fungsi biasa daripada subclass StatelessWidget . Contohnya seperti ini:
Widget function({ String title, VoidCallback callback }) {
return GestureDetector(
onTap: callback,
child: // some widget
);
}
Ini menarik karena membutuhkan kode yang jauh lebih sedikit daripada kelas yang lengkap. Contoh:
class SomeWidget extends StatelessWidget {
final VoidCallback callback;
final String title;
const SomeWidget({Key key, this.callback, this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: callback,
child: // some widget
);
}
}
Jadi saya bertanya-tanya: Apakah ada perbedaan selain sintaks antara fungsi dan kelas untuk membuat widget? Dan apakah praktik yang baik untuk menggunakan fungsi?
Jawaban:
TL; DR: Lebih suka menggunakan kelas daripada fungsi untuk membuat pohon widget yang dapat digunakan kembali .
EDIT : Untuk menebus beberapa kesalahpahaman: Ini bukan tentang fungsi yang menyebabkan masalah, tetapi kelas memecahkan beberapa.
Flutter tidak akan memiliki StatelessWidget jika suatu fungsi dapat melakukan hal yang sama.
Demikian pula, ini terutama ditujukan pada widget publik, dibuat untuk digunakan kembali. Tidak masalah untuk fungsi pribadi dibuat untuk digunakan hanya sekali - meskipun menyadari perilaku ini masih bagus.
Ada perbedaan penting antara menggunakan fungsi daripada kelas, yaitu: Framework tidak mengetahui fungsi, tetapi dapat melihat kelas.
Pertimbangkan fungsi "widget" berikut:
digunakan dengan cara ini:
Dan itu setara dengan kelas:
digunakan seperti itu:
Di atas kertas, keduanya tampak melakukan hal yang persis sama: Buat 2
Container
, dengan satu bertumpuk ke yang lain. Namun kenyataannya sedikit berbeda.Dalam kasus fungsi, pohon widget yang dihasilkan terlihat seperti ini:
Sedangkan dengan kelas, pohon widget adalah:
Ini penting karena mengubah cara framework berperilaku saat memperbarui widget.
Mengapa itu penting
Dengan menggunakan fungsi untuk membagi pohon widget Anda menjadi beberapa widget, Anda akan terkena bug dan kehilangan beberapa pengoptimalan kinerja.
Tidak ada jaminan bahwa Anda akan mendapatkan bug dengan menggunakan fungsi, tetapi dengan menggunakan kelas, Anda dijamin tidak akan menghadapi masalah ini.
Berikut beberapa contoh interaktif di Dartpad yang dapat Anda jalankan sendiri untuk lebih memahami masalahnya:
https://dartpad.dev/1870e726d7e04699bc8f9d78ba71da35
Contoh ini menunjukkan bagaimana dengan membagi aplikasi Anda menjadi beberapa fungsi, Anda mungkin secara tidak sengaja merusak hal-hal seperti
AnimatedSwitcher
https://dartpad.dev/a869b21a2ebd2466b876a5997c9cf3f1
Contoh ini menunjukkan bagaimana kelas memungkinkan pembangunan kembali pohon widget yang lebih terperinci, meningkatkan kinerja
https://dartpad.dev/06842ae9e4b82fad917acb88da108eee
Contoh ini menunjukkan bagaimana, dengan menggunakan fungsi, Anda mengekspos diri Anda pada penyalahgunaan BuildContext dan menghadapi bug saat menggunakan InheritedWidgets (seperti Tema atau penyedia)
Kesimpulan
Berikut adalah daftar perbedaan antara menggunakan fungsi dan kelas:
showDialogs
& serupa)ClassWidget
di pohon widget yang ditunjukkan oleh devtool, yang membantu memahami apa yang ada di layarJika terjadi pengecualian (seperti ProviderNotFound), kerangka kerja akan memberi Anda nama widget yang sedang dibangun. Jika Anda membagi pohon widget Anda hanya dalam fungsi +
Builder
, kesalahan Anda tidak akan memiliki nama yang bergunaSecara keseluruhan, menggunakan fungsi di atas kelas untuk menggunakan kembali widget dianggap sebagai praktik yang buruk karena alasan ini.
Anda bisa , tetapi itu mungkin menggigit Anda di masa depan.
sumber
Saya telah meneliti masalah ini selama 2 hari terakhir. Saya sampai pada kesimpulan berikut: TIDAK apa-apa untuk memecah bagian-bagian aplikasi menjadi beberapa fungsi. Idealnya fungsi tersebut mengembalikan a
StatelessWidget
, sehingga pengoptimalan dapat dilakukan, seperti membuatStatelessWidget
const
, sehingga tidak membangun kembali jika tidak perlu. Misalnya, potongan kode ini benar-benar valid:Penggunaan fungsi di sana baik-baik saja, karena mengembalikan a
const StatelessWidget
. Harap perbaiki saya jika saya salah.sumber
const
di depan kelas stateless untuk setiap kasus? Atau harus kasus tertentu? Jika ya, apakah itu?const
mana-mana. Misalnya, jika Anda memilikiStatelessWidget
kelas yang mengembalikan nilai yangText
berisi variabel, dan variabel itu berubah di suatu tempat, maka AndaStatelessWidget
harus dibangun kembali, sehingga dapat menunjukkan nilai yang berbeda, oleh karena itu tidak mungkinconst
. Saya pikir cara yang aman untuk menjelaskannya adalah ini: di mana pun Anda bisa, gunakanconst
, jika aman untuk melakukannya.Ada perbedaan besar antara fungsi apa dan fungsi kelas.
Mari saya jelaskan dari awal.π (hanya tentang keharusan)
Sejarah pemrograman, kita semua tahu dimulai dengan perintah dasar langsung (misalnya: Majelis).
Pemrograman terstruktur berikutnya hadir dengan kontrol Flow (misalnya: if, switch, while, for dll) Paradigma ini memberikan programmer untuk mengontrol aliran program secara efektif dan juga meminimalkan jumlah baris kode dengan loop.
Pemrograman prosedural berikutnya datang dan yang mengelompokkan instruksi ke dalam prosedur (fungsi). Ini memberi dua manfaat utama bagi programmer.
1. Pernyataan grup (operasi) ke dalam blok terpisah.
2. Dapat menggunakan kembali blok ini. (Fungsi)
Tetapi di atas semua paradigma tidak memberikan solusi untuk mengelola aplikasi. Pemrograman prosedural juga hanya dapat digunakan untuk aplikasi skala kecil. Itu tidak dapat digunakan untuk mengembangkan aplikasi web besar (misalnya: banking, google, youtube, facebook, stackoverflow dll), tidak dapat membuat kerangka kerja seperti android sdk, flutter sdk dan banyak lagi ......
Jadi, para insinyur melakukan lebih banyak penelitian untuk mengelola program dengan cara yang tepat.
Akhirnya Pemrograman Berorientasi Objek hadir dengan semua solusi untuk mengelola aplikasi dalam skala apa pun. (Dari hello world hingga Triliun orang menggunakan pembuatan sistem misalnya-google, amazon, dan saat ini 90% aplikasi).
Di OOP semua aplikasi dibangun di sekitar Objek. Artinya aplikasi adalah kumpulan dari objek-objek ini.
jadi objek adalah bangunan dasar untuk aplikasi apa pun.
class (objek saat runtime) mengelompokkan data dan fungsi yang terkait dengan variabel tersebut (data). jadi objek terdiri dari data dan operasi terkaitnya.
[Di sini saya tidak akan menjelaskan tentang oop]
πππOk Sekarang Mari datang untuk kerangka flutter.πππ
-Dart mendukung prosedural dan oop Tapi, kerangka Flutter sepenuhnya dibangun dengan menggunakan kelas (oop). (Karena kerangka besar yang dapat dikelola tidak dapat dibuat menggunakan prosedural)
Di sini saya akan membuat daftar alasan mereka menggunakan kelas, bukan fungsi untuk membuat widget.πππ
1 - Sering kali metode build (widget anak) memanggil jumlah fungsi sinkron dan asinkron.
Ex:
jadi metode build perlu disimpan dalam widget kelas yang terpisah (karena semua metode lain yang dipanggil oleh metode build () dapat disimpan dalam satu kelas)
2 - Menggunakan kelas widget Anda dapat membuat nomor dari kelas lain tanpa menulis kode yang sama berulang kali (** Use Of Inheritance ** (extends)).
Dan juga menggunakan warisan (memperpanjang) dan polimorfisme (menimpa) Anda dapat membuat kelas khusus sendiri. (Di bawah contoh, Di sana saya akan menyesuaikan (Menimpa) animasi dengan memperluas MaterialPageRoute (karena transisi defaultnya saya ingin menyesuaikan) .π
3 - Fungsi tidak dapat menambahkan kondisi untuk parameternya, Tetapi menggunakan konstruktor widget kelas Anda dapat melakukan ini.
Di bawah contoh Kodeπ (fitur ini banyak digunakan oleh widget kerangka kerja)
4 - Fungsi tidak dapat menggunakan const dan widget Kelas dapat menggunakan const untuk konstruktornya. (yang mempengaruhi kinerja utas utama)
5 - Anda dapat membuat sejumlah widget independen menggunakan kelas yang sama (instance dari kelas / objek) Tetapi fungsi tidak dapat membuat widget independen (instance), tetapi dapat menggunakan kembali.
[setiap instance memiliki variabel instance sendiri-sendiri dan yang sepenuhnya independen dari widget (objek) lain, Tetapi variabel lokal fungsi bergantung pada setiap pemanggilan fungsi * (yang berarti, ketika Anda mengubah nilai variabel lokal, itu mempengaruhi semua bagian lain dari aplikasi yang menggunakan fungsi ini)]
Ada banyak Keuntungan di kelas dibandingkan fungsi .. (di atas hanya beberapa kasus penggunaan)
π€― Pikiran Terakhir Saya
Jadi jangan gunakan Functions sebagai blok penyusun aplikasi Anda, gunakan hanya untuk melakukan Operasi. Jika tidak, ini menyebabkan banyak masalah yang tidak dapat ditangani saat aplikasi Anda menjadi skalabel .
ππππππππππππππππππππππππππππππππππππππππππππππππππ πππππππ
ANDA TIDAK DAPAT MENGUKUR KUALITAS PROGRAM DENGAN JUMLAH LAPORAN (atau baris) YANG DIGUNAKAN OLEHnya
ππππππππππππππππππππππππππππππππππππππππππππππππππ πππππππ
Terima kasih sudah membaca
sumber
shrinkHelper() { return const SizedBox.shrink(); }
sama seperti menggunakanconst SizedBox.shrink()
sebaris di pohon widget Anda, dan dengan menggunakan fungsi pembantu Anda dapat membatasi jumlah penumpukan di satu tempat.Saat Anda memanggil widget Flutter, pastikan Anda menggunakan kata kunci const. Sebagai contoh
const MyListWidget();
sumber
const
kata kunci saat memanggil widget stateless yang difaktorkan ulang, itu hanya boleh dipanggil sekali.