Belajar Flutter - Advanced State Management
Episode 10 of 23

Belajar Flutter - Advanced State Management

Episode ini naik kelas ke state management skala menengah: memilih dan memakai pattern Provider, Riverpod, Bloc, GetX, dan MobX, memahami reactive state flow dan dependency injection, mengelola state kompleks dengan modularization, serta kriteria memilih arsitektur sesuai ukuran aplikasi.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Pendahuluan

setState dan Provider cukup untuk aplikasi kecil, tetapi saat fitur bertambah — auth, keranjang belanja, sinkronisasi, notifikasi — state management harus diorganisasi dengan disiplin. Episode 10 membandingkan pattern yang paling banyak dipakai komunitas dan membantu kalian memilih dengan alasan, bukan ikut-ikutan.

Kita membahas Provider, Riverpod, Bloc, GetX, dan MobX, memahami reactive state flow dan dependency injection, teknik modularization untuk state kompleks, serta kerangka berpikir memilih arsitektur berdasarkan ukuran dan tim.

Pattern: Provider, Riverpod, Bloc, GetX, MobX

Sekilas Lima Pattern

  • Provider: resmi Google, sederhana, dibangun di atas InheritedWidget. Bagus untuk memulai.
  • Riverpod: evolusi Provider yang compile-safe dan testable tanpa BuildContext.
  • Bloc: berbasis event dan state, arsitektur ketat, populer untuk tim besar.
  • GetX: all-in-one dengan routing dan dependency injection, sangat ringkas.
  • MobX: reaktif berbasis observable, mirip dengan konsep state management di React.
Memasang riverpod
flutter pub add flutter_riverpod

Riverpod dalam Sekilas

Dengan Riverpod, state didefinisikan sebagai provider terpisah dari widget:

Provider Riverpod sederhana
final counterProvider = StateProvider<int>((ref) => 0);
 
class CounterScreen extends ConsumerWidget {
  const CounterScreen({super.key});
 
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterProvider);
    return Text('Nilai: $count');
  }
}

StateProvider menyimpan nilai sederhana dan ref.watch(counterProvider) membuat widget bereaksi terhadap perubahannya. ConsumerWidget menggantikan StatelessWidget untuk widget yang mengonsumsi provider.

Reactive State Flow dan Dependency Injection

Satu Arah Aliran Data

Semua pattern di atas mengikuti prinsip unidirectional data flow: state menghasilkan UI, interaksi menghasilkan event, event mengubah state, lalu siklus berulang. Kesalahan paling umum adalah memutasi state dari sembarang tempat tanpa jalur yang jelas.

Dependency Injection Melalui Provider

Provider bukan hanya untuk state — juga untuk membagikan object seperti repository atau client HTTP:

Injection repository ke provider
final postRepositoryProvider = Provider<PostRepository>((ref) {
  return PostRepository(httpClient: dio);
});

postRepositoryProvider membangun PostRepository sekali dan membagikannya ke seluruh aplikasi. Ini adalah dependency injection sederhana: widget menerima dependensi lewat provider, bukan membuatnya sendiri, sehingga mudah ditimpa dengan mock saat testing.

Mengelola State Kompleks dan Modularization

Pecah State per Fitur

Aplikasi menengah membutuhkan pemisahan state per domain:

  • AuthController — sesi dan token.
  • CartController — isi keranjang.
  • OrderController — status pesanan.

Jangan satukan semua state dalam satu object raksasa. Setiap fitur punya provider atau controller sendiri, dan layar mengonsumsi hanya yang dibutuhkannya.

Controller per domain
class CartController extends ChangeNotifier {
  final List<Item> _items = [];
  int get totalBarang => _items.length;
 
  void tambah(Item item) {
    _items.add(item);
    notifyListeners();
  }
}

CartController mengelola satu tanggung jawab. Dengan pola ini, perubahan satu domain tidak mengguncang domain lain — kunci maintainability.

Perhatikan Batas Rebuild

Semakin halus granularity provider, semakin sedikit widget yang rebuild saat state berubah. Aturan praktis: dengarkan di level terkecil. Jangan watch state besar di root jika hanya satu nilai yang dipakai — ini penyebab jank yang akan kita bahas di episode 15.

Memilih Arsitektur Sesuai Ukuran Aplikasi

Kerangka Keputusan

Panduan memilih pattern:

  • Prototipe dan aplikasi kecil: Provider atau Riverpod — cepat dan cukup.
  • Tim besar dengan kebutuhan disiplin: Bloc — event dan state yang eksplisit.
  • Developer yang ingin produktivitas maksimal: GetX — minimal boilerplate.
  • Familiar dengan ekosistem reaktif: MobX.
Membandingkan dependency terpasang
flutter pub deps --style=compact

flutter pub deps --style=compact menampilkan pohon dependency dalam satu baris per package — praktis untuk memeriksa apa saja yang sudah masuk sebelum menambah pattern baru.

Konsistensi Mengalahkan Dogma

Arsitektur terbaik adalah yang dipahami seluruh tim. Apapun pilihan kalian, dokumentasikan alur state di README, gunakan satu pattern secara konsisten, dan jangan mencampur tiga pattern dalam satu project tanpa alasan. Episode 20 akan memetakan ini ke arsitektur berskala production.

Penutup

Inti yang harus dibawa pulang:

  • Provider untuk memulai; Riverpod, Bloc, GetX, dan MobX sebagai alternatif matang.
  • Semua pattern mengikuti unidirectional data flow.
  • Pakai provider untuk dependency injection, bukan hanya state.
  • Pecah state per domain: auth, cart, order masing-masing punya controller.
  • Dengarkan state di level widget terkecil untuk meminimalkan rebuild.
  • Pilih arsitektur berdasarkan ukuran aplikasi dan kebutuhan tim, lalu konsisten.

Di episode 11 selanjutnya kita membahas navigation dan app architecture — perbedaan Navigator 1.0 dan Navigator 2.0, named routes, nested routes, dan deep linking, modular app architecture dan feature modules, serta code organization dan separation of concerns. Struktur project kalian mulai beranjak ke skala nyata.

Belajar Flutter - Advanced State Management | Belajar Flutter