17 April 2025 ・ 8 min read

Memilih State Management Terbaik untuk Aplikasi Flutter

Faisal Mahadi
Mobile Apps Developer | Android Enthusiast | Keep Learning | Android Dev Serta Owner Hariankoding.com
10
2
1
2
2
1
2
0
0
SHARE
Memilih State Management Terbaik untuk Aplikasi Flutter
👍 2 ❤️ 1 💡 2 🔥 2 🙌 1 🥳 2

Flutter adalah framework pengembangan aplikasi yang powerful, tetapi salah satu tantangan terbesar bagi developer adalah memilih state management yang tepat. State management membantu mengelola data dan UI secara efisien, memastikan aplikasi tetap responsif dan mudah dikembangkan.

Pada blog kali ini, kita akan membahas beberapa state management populer di Flutter, kelebihan, kekurangan, serta rekomendasi berdasarkan kebutuhan proyek kalian.

1. Provider: Solusi Sederhana untuk Pemula

State management Provider adalah salah satu metode (atau pola) dalam pengelolaan state di aplikasi Flutter. Provider sendiri merupakan package resmi yang direkomendasikan oleh tim Flutter, karena ringan, efisien, dan mudah digunakan.

Package: provider

Kelebihan:

  • Mudah dipahami dan digunakan.
  • Direkomendasikan oleh tim Flutter.
  • Cocok untuk proyek kecil hingga menengah.

Kekurangan:

❌ Kurang cocok untuk aplikasi kompleks dengan banyak state.

Kapan Menggunakan Provider?

  • Jika kalian baru belajar state management.
  • Untuk aplikasi dengan logika bisnis sederhana.

Ilustrasi sederhana:

1. Buat state-nya

class Counter with ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners(); // kasih tahu UI untuk update
  }
}

2. Daftarkan provider-nya di atas widget tree

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (_) => Counter(),
      child: MyApp(),
    ),
  );
}

3. Gunakan state di UI

class CounterWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counter = Provider.of<Counter>(context);

    return Column(
      children: [
        Text('Count: ${counter.count}'),
        ElevatedButton(
          onPressed: counter.increment,
          child: Text('Tambah'),
        ),
      ],
    );
  }
}

2. Riverpod: Pengganti Provider yang Lebih Kuat

Riverpod adalah salah satu state management (pengelola status/data) di Flutter, yang dirancang untuk menggantikan dan memperbaiki beberapa kekurangan dari Provider, yang merupakan pendahulunya. Riverpod menawarkan pendekatan yang lebih fleksibel, aman, dan mudah diuji untuk mengelola dan membagikan data antar bagian aplikasi Flutter.

Package: flutter_riverpod

Kelebihan:

  • Tidak tergantung pada BuildContext.
  • Lebih fleksibel dan aman dibanding Provider.
  • Cocok untuk testing dan dependency injection.

Kekurangan:

❌ Kurva belajar sedikit lebih tinggi.

Kapan Menggunakan Riverpod?

  • Jika kalian butuh solusi lebih kuat dari Provider.
  • Untuk proyek menengah hingga besar.

Contoh Penggunaan Sederhana:

1. Tambahkan dependency:

dependencies:
  flutter_riverpod: ^2.0.0

2. Buat Provider:

import 'package:flutter_riverpod/flutter_riverpod.dart';

final counterProvider = StateProvider<int>((ref) => 0);

3. Gunakan di UI:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

void main() {
  runApp(ProviderScope(child: MyApp())); // Wrap app with ProviderScope
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: HomePage());
  }
}

class HomePage extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterProvider);
    
    return Scaffold(
      appBar: AppBar(title: Text('Riverpod Example')),
      body: Center(child: Text('Count: $count')),
      floatingActionButton: FloatingActionButton(
        onPressed: () => ref.read(counterProvider.notifier).state++,
        child: Icon(Icons.add),
      ),
    );
  }
}

3. Bloc: State Management untuk Aplikasi Kompleks

State management BLoC (singkatan dari Business Logic Component) di Flutter adalah sebuah pola arsitektur yang memisahkan logika bisnis (business logic) dari tampilan (UI). Tujuannya adalah untuk membuat kode menjadi lebih terstruktur, terpisah, dan mudah diuji.

Konsep Inti BLoC

Di dalam BLoC, ada tiga komponen utama:

  1. Event Representasi aksi yang dilakukan oleh user atau sistem (misalnya: AddToCart, LoadProduct, SubmitOrder).
  2. State Representasi kondisi aplikasi pada satu waktu tertentu (misalnya: CartLoading, CartLoaded, CartError).
  3. Bloc Komponen yang menerima event, memproses logika, dan mengeluarkan state baru berdasarkan event tersebut.

Package: flutter_bloc

Kelebihan:

  • Memisahkan logika bisnis dari UI dengan jelas.
  • Cocok untuk aplikasi besar dengan banyak interaksi.

Kekurangan:

❌ Membutuhkan lebih banyak boilerplate.

Kapan Menggunakan Bloc?

  • Jika kalian mengembangkan aplikasi enterprise.
  • Ketika membutuhkan manajemen state yang terstruktur.

Contoh Gampang (CartBloc)

Misalnya kamu punya fitur keranjang:

Event:

abstract class CartEvent {}

class AddItemToCart extends CartEvent {
  final String productId;
  AddItemToCart(this.productId);
}

State:

abstract class CartState {}

class CartInitial extends CartState {}
class CartLoading extends CartState {}
class CartLoaded extends CartState {
  final List<String> items;
  CartLoaded(this.items);
}

Bloc:

class CartBloc extends Bloc<CartEvent, CartState> {
  List<String> _cartItems = [];

  CartBloc() : super(CartInitial()) {
    on<AddItemToCart>((event, emit) {
      emit(CartLoading());
      _cartItems.add(event.productId);
      emit(CartLoaded(List.from(_cartItems)));
    });
  }
}

Di UI:

BlocBuilder<CartBloc, CartState>(
  builder: (context, state) {
    if (state is CartLoading) {
      return CircularProgressIndicator();
    } else if (state is CartLoaded) {
      return ListView(
        children: state.items.map((item) => Text(item)).toList(),
      );
    }
    return Text('Keranjang kosong');
  },
);

4. GetX: Solusi Cepat dengan Minimal Boilerplate

State management GetX di Flutter adalah salah satu pendekatan populer untuk mengelola state (keadaan/data) aplikasi, serta routing dan dependency injection dengan cara yang mudah, cepat, dan efisien. GetX menjadi pilihan banyak developer karena sintaksnya yang simpel dan performanya yang baik.

Package: get

Kelebihan:

  • Sangat ringan dan mudah digunakan.
  • Mendukung navigasi, dependency injection, dan state management.

Kekurangan:

❌ Kurang terstruktur untuk proyek besar.

Kapan Menggunakan GetX?

  • Untuk prototyping cepat.
  • Jika ingin mengurangi boilerplate.

GetX dalam State Management

GetX menyediakan beberapa cara untuk mengelola state:

  1. Reactive State (Obx)

    • Gunakan variabel Rx (Reactive), lalu bungkus UI dengan Obx untuk mendeteksi perubahan otomatis.

    • Contoh:

      class CounterController extends GetxController {
        var count = 0.obs; // .obs membuat variabel jadi observable
      
        void increment() {
          count++;
        }
      }
      
      // Di UI
      final controller = Get.put(CounterController());
      
      Obx(() => Text("Count: ${controller.count}"));
      
  2. Simple State (update())

    • Gunakan dengan GetBuilder, cocok untuk state yang tidak terlalu kompleks.

    • Contoh:

      class CounterController extends GetxController {
        int count = 0;
      
        void increment() {
          count++;
          update(); // memicu update UI
        }
      }
      
      // Di UI
      GetBuilder<CounterController>(
        init: CounterController(),
        builder: (controller) => Text("Count: ${controller.count}"),
      );
      
  3. Dependency Injection

    • GetX juga bisa menyuntikkan dan mengatur controller dengan sangat mudah.

    • Contoh:

      final controller = Get.put(CounterController()); // dibuat sekali, bisa dipakai di mana-mana
      
  4. Routing

    • Navigasi dengan cara yang singkat dan powerful.

    • Contoh:

      Get.to(DetailPage());
      Get.back();
      Get.offAll(HomePage());
      

5. MobX: Reactive Programming di Flutter

MobX adalah salah satu state management library di Flutter yang digunakan untuk mengelola dan mengamati perubahan state secara reaktif. MobX diambil dari dunia JavaScript (React) dan diadaptasi untuk Flutter dengan pendekatan reactive programming.

Konsep Inti MobX di Flutter:

  1. Observable (State): Ini adalah data yang bisa berubah dan bisa diamati. Contoh: variabel counter, list produk, dll.
  2. Action: Fungsi yang mengubah observable. Semua perubahan state sebaiknya dibungkus dalam action agar MobX bisa melacak perubahan dengan jelas.
  3. Reaction: Efek samping yang dijalankan ketika observables berubah. Contohnya seperti rebuild UI saat data berubah.
  4. Computed: Nilai yang dihitung dari observables lainnya. Contoh: isCartEmpty bisa dihitung dari cartItems.isEmpty.

Package: mobx

Kelebihan:

  • Reactive programming dengan sedikit boilerplate.
  • Cocok untuk developer yang suka pendekatan observables.

Kekurangan:

❌ Membutuhkan code generation (build_runner).

Kapan Menggunakan MobX?

  • Jika kalian familiar dengan reactive programming.
  • Untuk aplikasi yang membutuhkan reaktivitas tinggi.

Cara Kerja:

Kamu menandai variabel sebagai @observable, lalu ubah nilainya lewat @action, dan UI otomatis akan rebuild jika kamu menggunakan Observer.

Contoh Sederhana:

1. Tambahkan Dependency:

dependencies:
  flutter_mobx: ^2.0.6
  mobx: ^2.0.6

dev_dependencies:
  build_runner: ^2.1.7
  mobx_codegen: ^2.0.5

2. Buat Store (state-nya):

import 'package:mobx/mobx.dart';
part 'counter_store.g.dart';

class CounterStore = _CounterStore with _$CounterStore;

abstract class _CounterStore with Store {
  @observable
  int counter = 0;

  @action
  void increment() {
    counter++;
  }
}

Lalu jalankan perintah:

flutter pub run build_runner build

3. Gunakan di UI:

final counterStore = CounterStore();

Observer(
  builder: (_) => Text('${counterStore.counter}'),
)

ElevatedButton(
  onPressed: () => counterStore.increment(),
  child: Text('Tambah'),
)

6. Redux: State Management Terpusat

Redux di Flutter adalah state management pattern yang diadaptasi dari Redux di JavaScript (terutama React). Dia fokus pada konsep satu sumber kebenaran (single source of truth), state yang tidak bisa diubah langsung (immutable), dan alur data satu arah (unidirectional flow).

Konsep Inti Redux:

  1. Store: Tempat semua state disimpan. Hanya ada satu store utama.
  2. State: Representasi dari semua data aplikasi kamu. State itu immutable, jadi nggak boleh diubah langsung.
  3. Action: Objek yang mendeskripsikan apa yang ingin dilakukan (misalnya: { type: 'ADD_TODO' }).
  4. Reducer: Fungsi yang menerima state dan action, lalu mengembalikan state baru.
  5. Middleware (opsional): Tempat untuk menangani side-effects seperti API call, logging, dll.

Alur Redux:

UI (View)
  ↓
Dispatch(Action)
  ↓
Reducer (mengubah state)
  ↓
Store (update state)
  ↓
UI rebuild berdasarkan state baru

Package: flutter_redux

Kelebihan:

  • Cocok untuk state global yang kompleks.
  • Memudahkan debugging dengan sistem yang terprediksi.

Kekurangan:

❌ Boilerplate tinggi.

Kapan Menggunakan Redux?

  • Jika kalian butuh state management yang sangat terstruktur.
  • Untuk aplikasi dengan banyak shared state.

Contoh Sederhana Redux di Flutter

1. Tambahkan dependency:

dependencies:
  flutter_redux: ^0.10.0
  redux: ^5.0.0

2. Definisikan State:

class CounterState {
  final int count;
  CounterState(this.count);
}

3. Definisikan Action:

class IncrementAction {}

4. Buat Reducer:

CounterState counterReducer(CounterState state, dynamic action) {
  if (action is IncrementAction) {
    return CounterState(state.count + 1);
  }
  return state;
}

5. Buat Store:

final store = Store<CounterState>(
  counterReducer,
  initialState: CounterState(0),
);

6. Gunakan di UI:

void main() {
  runApp(MyApp(store: store));
}

class MyApp extends StatelessWidget {
  final Store<CounterState> store;

  MyApp({required this.store});

  @override
  Widget build(BuildContext context) {
    return StoreProvider(
      store: store,
      child: MaterialApp(
        home: CounterPage(),
      ),
    );
  }
}

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: StoreConnector<CounterState, int>(
          converter: (store) => store.state.count,
          builder: (context, count) => Text('$count'),
        ),
      ),
      floatingActionButton: StoreConnector<CounterState, VoidCallback>(
        converter: (store) => () => store.dispatch(IncrementAction()),
        builder: (context, callback) => FloatingActionButton(
          onPressed: callback,
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

Kesimpulan: State Management Mana yang Harus Dipilih?

Kebutuhan State Management
Pemula / Proyek kecil Provider / GetX
Proyek menengah-besar Riverpod / Bloc
Reactive programming MobX
State global terpusat Redux
Prototyping cepat GetX

Tips Memilih State Management:

  • Pelajari Provider atau Riverpod jika kalia baru memulai.
  • Gunakan Bloc/Riverpod untuk proyek besar dan terstruktur.
  • Pilih GetX jika ingin pengembangan cepat dengan sedikit kode.

Dengan memilih state management yang tepat, kalian dapat meningkatkan maintainability, performa, dan skalabilitas aplikasi Flutter kalian. 🚀

Apa state management favorit teman-teman? Bagikan di komentar! 💬


KEBIJAKAN KOMENTAR

Saat memberikan komenatar silahkan memberikan informasi lengkap tentang error, seperti: screenshot, link kode, dll. Baca aturan komentar kami