Jangan Pakai setState (Flutter State Management)
Intro
Well, halo semua. Ya ya saya tau ini sudah lama dan saya baru muncul lagi ke permukaan, jadi maafkan saya :(. So seperti yg saya mention di artikel sebelumnya, pada tulisan kali ini saya akan memberikan pengetahuan saya tentang kenapa kita harus menghindari penggunaan setState pada Flutter. So let’s go!
State Management
Sebelum kita pergi lebih jauh, mari kita mengenali apa itu state management. Jadi dikutip dari kotakode.com, state management adalah :
Sebuah cara untuk mengatur data / state kita bekerja, bisa juga untuk memisahkan antara logic dan view dimana logic tersebut juga bisa re-usable.
Dari pemahaman saya sendiri, state management adalah suatu tools atau metode yang digunakan untuk mengatur alur dari suatu data, bagaimana kita mengolah data dalam sebuah tampilan view atau halaman aplikasi. Berdasarkan kutipan di atas, state management juga bisa digunakan sebagai fungsi yang berisi logic yang kita perlukan untuk dijalankan terpisah dari view, sehingga kode yang kita hasilkan lebih mudah untuk dibaca, di-debug, dan bisa jadi dapat digunakan pada tempat lain.
Pada Flutter sendiri sudah memiliki state management bawaannya yang sudah disebut diatas, yaitu setState. Pada artikel sebelumnya kita menggunakan setState, jadi bagaimana cara kerjanya ?. Jadi pada proyek sebelumnya, kita memakai setState sebagai sarana untuk memperbarui data saat kita menambahkan, menyelesaikan, dan mengembalikan “data todo” yang akan maupun yang telah kita buat. Bagaimana itu terjadi ? saya tidak akan menjelaskan secara teknis tapi dengan penjelasan yg menurut saya paling tidak dapat dipahami manusia awam (silahkan cari penjelasan teknis sendiri hehehe .-.).
Jadi saat kita melakukan sesuatu kepada data todo kita, maka program akan menjalankan perintah sesuai logika yang sudah kita buat yaitu tambah, selesai, atau mengembalikan data, akan tetapi jika kita tidak menggunakan setState maka tidak akan ada sesuatu yang berubah pada tampilan kita (dalam kasus ini data yg sudah kita olah tidak muncul pada tampilan kita), sedangkan data pada onGoingList dan finishedList sudah diperbarui. Maka dengan adanya setState, fungsi tersebut memaksa aplikasi kita melakukan semacam “hot-reload” view yaitu memaksa program memperbarui tampilan aplikasi kita (berdasarkan pemahaman yg menurut saya mudah dicerna .-.). Sehingga apa yang ada pada tampilan di layar, sama dengan data yang ada pada onGoingList dan finishedList.
Lalu kenapa setState perlu dihindari jika berguna ?
Kenapa ? karena tentu saja ini bisa menjadi hal yang bisa mempengaruhi performa aplikasi. Bingung ? jadi begini, karena ini memaksa program melakukan “hot-reload” maka sama saja membangun ulang tampilan dari awal hingga akhir dengan data terbaru. Bayangkan jika kita memiliki satu screen view yang memiliki banyak fitur yang mungkin 10, 20, 30, atau lebih dimana itu adalah wajar jika kita sudah mengerjakan proyek enterprise, kemudian karena kita perlu mengolah data menggunakan setState tadi, kita harus membangun ulang dari awal semua fitur itu hanya untuk memperbarui data yang mungkin cuma ada pada satu fitur. Hal ini bukanlah cara terbaik, karena dalam dunia software engineer perbedaan beberapa milisecond sangat berharga terhadap performa aplikasi.
Resolusi
So, bagaimana kalau kita ingin mengatur pengolahan data kita tanpa menggunakan setState ? tenang teman-teman, Flutter sendiri memiliki banyak library/package state management yang bisa dipakai yang dapat memberikan performa lebih baik dari pada hanya memakai setState, yaitu BloC, Provider, GetX, Riverpod, Redux, MobX dan masih banyak lagi yang bisa teman-teman akses di sini.
Kenapa kita perlu memakai package tersebut ? percayalah teman-teman terdapat perbedaan saat kita memakainya, saya akan memberikan contoh dari salah satu package tersebut yaitu GetX, so it’s coding time! :D
First Move
Menggunakan proyek sebelumnya (dapat dilihat disini) dan sebelum memulai coding, kita perlu meng-install package GetX dengan dengan menambahkan packgae pada pubspec.yaml pada depedencies seperti berikut
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
get:
Kemudian jalankan command pada terminal, yaitu
flutter pub get
todo_controller.dart
Kemudian tambahkan file baru dengan kode seperti berikut
Pada file tersebut berisi fungsi yang mengganti penggunaan useState kita seperti addItem, finishItem, undoItem, dan inisiasi variabel. Sehingga setelah ini, struktur proyek kita akan menjadi seperti ini
lib ---
|--- controllers
| |--- todo_controller.dart
|
|--- constant
| |--- constant.dart
|
|--- models
| |--- todo_model.dart
|
|--- ui
| |--- screen
| | |----- todo_screen.dart
| |
| |--- widgets
| |----- todo_cart.dart
|
|--- main.dart
main.dart
Setelah itu kita update kodingan pada main.dart menjadi seperti berikut
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: ‘Flutter Demo’,
home: MyHomePage(),
);
}
}
todo_screen.dart
Pada file ini, terdapat beberapa perubahan pada fungsi buildOnGoingSection, buildDoneSection, dan onPress pada “ElevatedButton”, serta pada pendefinisian variabel. Jadi tolong perhatikan.
Perbedaan
Jadi ya kita sudah bisa lihat perbedaannya disini, yaitu ada file baru hahaha :D just kidding. Pada todo screen yang baru, saya meninggalkan fungsi print, dimana akan memberi output “BODY” jika yang dibangun ulang adalah seluruh view, “OBX ON GOING SECTION” apabila hanya fungsi buildOnGoingSection yang dibangun ulang, dan “OBX DONE SECTION” apabila hanya fungsi buildDoneSection yang dibangun ulang. Sehingga apabila kita run aplikasi dan melakukan pengolahan data seperti tambah, finish, atau mengembalikan data, dengan menggunakan GetX ini, kita tidak perlu membangun ulang keseluruhan view yang ada, akan tetapi terisolasi hanya pada fungsi atau fitur yang perlu kita perbarui. Berikut adalah ilustrasinya
Dari ilustrasi di atas, bisa dilihat tidak ada output bertuliskan BODY karena GetX hanya akan membangun ulang fungsi yang kita perlukan, dimana kita sudah membungkus fungsi pada buildOnGoingSection dan buildDoneSection (berdasarkan output yang keluar “OBX DONE SECTION” atau “OBX ON GOING SECTION”) dengan Obx, sehingga GetX akan membangun ulang fungsi-fungsi pada Obx yang berhubungan dengan data yang sedang diolah.
Sekarang kita lihat apabila kita masih menggunakan setState seperti pada kodingan sebelumnya pada ilustrasi berikut
Bisa kita lihat bahwa menggunakan setState membuat aplikasi kita memberi output BODY yang berarti ini membuat program kita dibangun ulang dari awal untuk semua fitur yang ada, bukan pada fitur yang kita perlukan.
Kesimpulan
Yak kita sudah sampai diujung tulisan yang berisi kesimpulan, bahwa untuk membangun aplikasi yang lebih baik, maka kita harus menggunakan tools, teknik, cara ataupun teknologi yang lebih baik dan tepat. Dalam kasus ini, agar kita bisa memberikan performa yang lebih baik pada aplikasi kita, maka kita perlu menggunakan bantuan dari package untuk state management daripada hanya menggunakan setState. Saya tidak melarang teman-teman menggunakan setState, tapi saya lebih merekomendasikan menggunakan state management lain untuk membuat performa aplikasi kita lebih baik, untuk apa state management yang lebih baik kita gunakan ?, itu kembali kepada teman-teman, karena menurut saya pemilihan state management bisa tergantung fitur, waktu, dan lain-lain. Banyak variabel yang mempengaruhi keputusan pemilihan state management package, jadi apapun itu pastikan teman-teman menggunakannya sebaik mungkin.
So, sekian untuk artikel kali ini, semoga bermanfaat bagi teman-teman yang ingin lebih mendalami tentang Flutter. Saya menerima semua masukan untuk membuat artikel yang lebih baik dan mudah dipahami.
Sebelum berpisah mungkin kita bisa saling terhubung dengan mengunjungi saya dan See you ! untuk pembacaan kita selanjutnya, ehe.