返回網誌
指南2025年5月25日安安科技團隊閱讀時間 8 分鐘

FLUTTER 狀態
管理指南

為你的 Flutter 應用程式選擇合適狀態管理方案的完整指南。透過實用例子,比較 Provider、Bloc、Riverpod 等多種方案。

Flutter 狀態管理
// 簡報

狀態管理是任何 Flutter 應用程式的骨幹。它決定數據如何在應用程式內流動、組件之間如何溝通,並最終決定程式碼庫在不斷增長時的可維護性。

面對眾多選擇——Provider、Bloc、Riverpod、GetX、MobX——要挑選合適的方案可能令人無從入手。本指南會逐一拆解每種方案,配以實際例子,助你作出明智的決定。

PROVIDER:官方推薦之選

Provider 是 Google 推薦的狀態管理方案。它建基於 InheritedWidget 之上,提供簡單而可擴展的解決方案,適合絕大多數應用程式。

provider.dart
// Counter model
class CounterModel extends ChangeNotifier {
  int _count = 0;
  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }
}

// Setup Provider
ChangeNotifierProvider(
  create: (context) => CounterModel(),
  child: MyApp(),
)

// Consume in UI
Consumer<CounterModel>(
  builder: (context, counter, child) {
    return Text('Count: ${counter.count}');
  },
)

優點

  • Google 官方推薦
  • 簡單易學
  • 文檔齊全
  • 非常適合中小型應用程式

缺點

  • 在大型應用程式中容易變得混亂
  • 沒有內置的非同步處理
  • 缺乏測試工具
  • 樣板程式碼冗長

BLOC:可預測、易測試

Bloc(Business Logic Component)遵循響應式編程範式。它將展示層與業務邏輯分離,令應用程式高度可測試、行為可預測。

counter_bloc.dart
// Events
abstract class CounterEvent {}
class Increment extends CounterEvent {}
class Decrement extends CounterEvent {}

// States
abstract class CounterState {}
class CounterInitial extends CounterState {}
class CounterValue extends CounterState {
  final int count;
  CounterValue(this.count);
}

// Bloc
class CounterBloc extends Bloc<CounterEvent, CounterState> {
  CounterBloc() : super(CounterInitial()) {
    on<Increment>((event, emit) {
      emit(CounterValue(currentCount + 1));
    });
  }
}

// Usage
BlocBuilder<CounterBloc, CounterState>(
  builder: (context, state) {
    if (state is CounterValue) {
      return Text('Count: ${state.count}');
    }
    return Text('Count: 0');
  },
)

優點

  • 高度可測試
  • 狀態變化可預測
  • 非常適合複雜應用程式
  • 出色的 DevTools 支援

缺點

  • 學習曲線陡峭
  • 樣板程式碼繁多
  • 對簡單應用程式而言過於複雜
  • 需要理解 Stream 的概念

RIVERPOD:PROVIDER 2.0

Riverpod 出自 Provider 原作者之手,修正了 Provider 的許多限制,同時保持簡潔。它具備編譯期安全,而且不依賴 BuildContext。

riverpod.dart
// Provider definition
final counterProvider = StateNotifierProvider<CounterNotifier, int>(
  (ref) => CounterNotifier(),
);

class CounterNotifier extends StateNotifier<int> {
  CounterNotifier() : super(0);

  void increment() => state++;
  void decrement() => state--;
}

// Usage
class CounterWidget extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterProvider);
    
    return Column(
      children: [
        Text('Count: $count'),
        ElevatedButton(
          onPressed: () => ref.read(counterProvider.notifier).increment(),
          child: Text('Increment'),
        ),
      ],
    );
  }
}

優點

  • 編譯期安全
  • 不依賴 BuildContext
  • 內置緩存機制
  • 出色的開發體驗

缺點

  • 較新,社群規模較小
  • 版本更新時或有破壞性改動
  • 部分概念較為複雜
  • 從 Provider 遷移需花一番工夫

GETX:一站式全能方案

GetX 不止於狀態管理——它還內置路由、依賴注入及國際化功能,以極少的樣板程式碼和高效能見稱。

getx.dart
// Controller
class CounterController extends GetxController {
  var count = 0.obs;
  
  void increment() => count++;
  void decrement() => count--;
}

// Usage
class CounterWidget extends StatelessWidget {
  final CounterController controller = Get.put(CounterController());
  
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Obx(() => Text('Count: ${controller.count}')),
        ElevatedButton(
          onPressed: controller.increment,
          child: Text('Increment'),
        ),
      ],
    );
  }
}

優點

  • 樣板程式碼極少
  • 效能出色
  • 一站式解決方案
  • 容易上手

缺點

  • 並非 Google 官方推薦
  • 「魔法」行為可能難以捉摸
  • 與 GetX 生態系統緊密耦合
  • 可預測性不及其他方案

你應該選擇哪一個?

初學者之選

Provider 開始。它獲官方推薦、文檔齊全,學習曲線平緩。

適合:學習 Flutter、中小型應用程式、原型開發

大型應用程式

業務邏輯複雜、對可測試性要求高時,使用 Bloc。樣板程式碼的投入會在可維護性上得到回報。

適合:企業級應用程式、複雜狀態、團隊開發

現代應用程式

試試 Riverpod,享受最佳開發體驗與編譯期安全。它是 Flutter 狀態管理的未來。

適合:全新專案、重視開發體驗的團隊、大量非同步操作的應用程式

快速開發

需要極速開發、又不介意一點「魔法」時,選擇 GetX。非常適合 MVP 和獨立開發。

適合:MVP、個人專案、快速原型開發

狀態管理最佳實踐

1

盡量將狀態放在最接近使用它的地方。不要把所有東西都放進全域狀態。

2

將 UI 狀態與業務邏輯分離。載入狀態屬於 UI,業務數據屬於服務層。

3

盡可能讓狀態保持不可變。這樣可以減少錯誤,令除錯更輕鬆。

4

為狀態邏輯編寫測試。狀態管理屬於業務邏輯,理應獲得徹底測試。

5

不要過度設計。選擇能滿足當前需求的最簡單方案,日後隨時可以重構。

// 藍圖

你的 FLUTTER 應用程式需要協助?

我們的團隊對各大主流狀態管理方案均有實戰經驗。讓我們助你打造可擴展、易維護的 Flutter 應用程式!

聯絡我們
// 訊號放大

分享本指南