Overview #
State management adalah salah satu topik yang paling banyak diperdebatkan di ekosistem Flutter. Ada puluhan library, puluhan pendapat, dan setiap proyek tampaknya punya preferensinya sendiri. Tapi sebelum memilih library, kamu perlu memahami fondasi: apa itu state, kategori apa saja yang ada, dan kapan kamu benar-benar membutuhkan solusi di luar setState.
Apa itu State? #
State adalah data yang bisa berubah sepanjang lifetime aplikasi dan mempengaruhi tampilan UI. Setiap kali state berubah, Flutter me-rebuild widget yang bergantung pada state tersebut untuk mencerminkan nilai terbaru.
UI = f(State)
State berubah → Flutter rebuild UI → Tampilan diperbarui
Contoh sederhana: counter app. Nilai counter adalah state. Ketika tombol ditekan, nilai berubah, UI di-rebuild, angka baru tampil di layar.
State yang lebih kompleks: keranjang belanja e-commerce. Daftar produk, jumlah per item, kode promo, ongkos kirim — semua ini adalah state yang bisa berubah dan mempengaruhi berbagai bagian UI secara bersamaan.
Dua Kategori State #
Flutter secara konseptual membagi state menjadi dua kategori:
Ephemeral State (Local State) #
State yang hanya relevan untuk satu widget dan tidak perlu dibagikan ke widget lain. Flutter menyediakan StatefulWidget dan setState() untuk ini.
// Ephemeral state: hanya relevan di dalam widget ini
class _TabBarState extends State<TabBar> {
int _selectedIndex = 0; // hanya digunakan di sini
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: (i) => setState(() => _selectedIndex = i),
items: const [...],
);
}
}
Contoh ephemeral state yang tepat: tab yang aktif di bottom nav (jika tidak perlu persist), nilai sementara di text field, progress animasi, status expand/collapse accordion, visibilitas password toggle.
App State (Shared State) #
State yang perlu dibagikan ke beberapa widget atau halaman, atau perlu bertahan saat halaman berubah. Ini yang membutuhkan solusi state management yang lebih terstruktur.
// App state: keranjang belanja yang diakses dari banyak halaman
class KeranjangState {
final List<CartItem> items;
final int totalItems;
final double totalHarga;
// Diakses dari: ProductCard, CartIcon di AppBar, CartScreen, CheckoutScreen
}
Contoh app state yang tepat: status login pengguna, data profil, keranjang belanja, preferensi tema/bahasa, notifikasi yang belum dibaca, data yang di-fetch dari server.
Batas yang Fleksibel #
Tidak ada aturan kaku antara ephemeral dan app state. Sesuatu yang awalnya ephemeral bisa berkembang menjadi app state seiring aplikasi tumbuh. Tab aktif di bottom nav bisa jadi ephemeral, tapi jika kamu perlu menyimpannya ke disk agar persist saat restart, ia menjadi app state.
Kapan Butuh State Management Library? #
setState() adalah solusi yang valid dan sering diabaikan kapasitasnya. Tim Flutter sendiri menggunakannya di banyak contoh. Pertanyaan yang tepat bukan “pakai library apa?” tapi “apakah saya butuh library?”:
Cukup dengan setState() jika:
✓ State hanya digunakan dalam satu widget
✓ Tidak ada prop drilling lebih dari 2-3 level
✓ State tidak perlu diakses dari halaman yang berbeda
✓ Aplikasi skala kecil dengan sedikit halaman
Pertimbangkan library jika:
✗ State yang sama dibutuhkan di banyak bagian UI
✗ Prop drilling sudah melalui 3+ level widget
✗ Logika bisnis tercampur dengan kode UI
✗ Sulit menulis unit test untuk logika state
✗ Banyak developer bekerja di codebase yang sama
✗ State perlu di-sync dengan server (async state)
Peta Ekosistem State Management Flutter #
BUILT-IN (tanpa library eksternal):
setState() -- state lokal sederhana
ValueNotifier -- state lokal reaktif, performa lebih baik
ChangeNotifier -- state sederhana dengan multiple listener
InheritedWidget -- fondasi semua library (low-level)
StreamBuilder -- state dari Stream (real-time data)
FutureBuilder -- state dari Future (async data)
LIBRARY POPULER:
Provider -- wrapper InheritedWidget, resmi direkomendasikan
Mudah dipelajari, cocok untuk tim baru
Riverpod -- evolusi Provider, lebih aman dan fleksibel
Tidak butuh BuildContext, type-safe, testable
Bloc / Cubit -- arsitektur terstruktur dengan event-driven
Cocok untuk tim besar, enterprise, strict architecture
MobX -- reactive programming dengan code generation
Minimal boilerplate, familiar bagi developer React
Aliran Data di Flutter #
Memahami bagaimana data seharusnya mengalir adalah fondasi dari semua pendekatan state management:
DATA FLOW YANG BENAR (unidirectional):
Action/Event
↓
State berubah
↓
UI di-rebuild
Contoh: tombol ditekan → counter++ → Text('${counter}') rebuild
DATA FLOW YANG SALAH:
Widget A ←→ Widget B ←→ Widget C
(saling bergantung, sulit diprediksi, rawan bug)
Semua solusi state management modern — Provider, Riverpod, Bloc, MobX — mengikuti prinsip unidirectional data flow: data mengalir satu arah, dari state ke UI, bukan bolak-balik antar widget.
Perbandingan Singkat #
| setState | Provider | Riverpod | Bloc | MobX | |
|---|---|---|---|---|---|
| Kurva belajar | Rendah | Rendah | Sedang | Tinggi | Sedang |
| Boilerplate | Minimal | Rendah | Rendah-Sedang | Tinggi | Rendah (codegen) |
| Testability | Sulit | Sedang | Tinggi | Tinggi | Sedang |
| Skalabilitas | Rendah | Sedang | Tinggi | Tinggi | Sedang |
| Cocok untuk | App kecil | Small-medium | Medium-large | Large/enterprise | Medium |
| Reactive | Manual | Semi-auto | Auto | Stream-based | Auto |
Rekomendasi untuk Mulai #
Tidak ada jawaban universal — pilihan terbaik bergantung pada konteks. Tapi ada panduan yang bisa membantu:
Jika kamu baru belajar Flutter: mulai dengan setState dan ValueNotifier. Pahami dulu bagaimana state bekerja sebelum menambah abstraksi library.
Jika kamu membangun aplikasi production menengah: Riverpod adalah pilihan modern yang paling direkomendasikan saat ini — aman, scalable, dan testable.
Jika kamu bekerja di tim besar atau enterprise: Bloc memberikan struktur yang paling ketat dan predictable — cocok untuk kolaborasi banyak developer.
Jika kamu familiar dengan React dan reactive programming: MobX akan terasa sangat familiar dan produktif.
Artikel-artikel berikutnya membahas setiap pendekatan secara mendalam dengan contoh kode yang bisa langsung diimplementasikan.
Ringkasan #
- State adalah data yang bisa berubah dan mempengaruhi tampilan UI. UI adalah fungsi dari state:
UI = f(State).- Ada dua kategori: ephemeral state (hanya relevan di satu widget, gunakan
setState) dan app state (dibagikan ke banyak bagian, butuh solusi lebih terstruktur).- Tidak semua aplikasi butuh state management library —
setStatedanValueNotifierbisa sangat jauh jika digunakan dengan tepat.- Ekosistem Flutter punya banyak pilihan: Provider (mudah), Riverpod (modern dan powerful), Bloc (terstruktur dan enterprise-ready), MobX (reactive dengan codegen).
- Semua solusi modern mengikuti unidirectional data flow — data mengalir satu arah dari state ke UI, bukan bolak-balik.
- Pilih berdasarkan: skala aplikasi, ukuran tim, pengalaman developer, dan kebutuhan testability — bukan hanya berdasarkan popularitas.
← Sebelumnya: Widget Best Practice Berikutnya: setState & ValueNotifier →