← 返回首页

Flutter 状态管理深度对比:Provider vs Riverpod vs BLoC

从原理到实战,对比三大主流状态管理方案的优劣,帮你找到最适合自己项目的选择。

为什么需要状态管理

Flutter 的 Widget 树是单向数据流的。当状态只在单个 Widget 内部时,用 setState() 足够了。但当多个页面需要共享同一份数据时,逐层传递 props 会让代码变得混乱不堪——这就是状态管理要解决的问题。

Provider

Provider 是 Flutter 官方推荐的轻量级方案,基于 InheritedWidget 封装。核心思路是将状态对象注入 Widget 树,子孙节点通过 context.watch()context.read() 订阅。

// 定义状态
class CounterNotifier extends ChangeNotifier {
  int _count = 0;
  int get count => _count;

  void increment() {
    _count++;
    notifyListeners(); // 通知所有监听者重建
  }
}

// 注入
ChangeNotifierProvider(
  create: (_) => CounterNotifier(),
  child: const MyApp(),
)

// 消费
Text('${context.watch<CounterNotifier>().count}')

优点:简单直观,上手快,官方文档完善。

缺点:依赖 BuildContext,测试时需要额外包裹 Widget 树;大型项目容易出现 Provider 嵌套地狱。

Riverpod

Riverpod 由 Provider 作者重新设计,彻底摆脱对 BuildContext 的依赖。所有 Provider 都是全局声明的顶级变量,编译期即可检测错误。

// 声明 Provider(全局,类型安全)
final counterProvider = StateNotifierProvider<CounterNotifier, int>(
  (ref) => CounterNotifier(),
);

class CounterNotifier extends StateNotifier<int> {
  CounterNotifier() : super(0);
  void increment() => state++;
}

// 在 Widget 中使用(ConsumerWidget)
class CounterPage extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterProvider);
    return Text('$count');
  }
}

优点:类型安全,可组合,测试友好,支持异步状态(AsyncValue)。

缺点:概念较多(Provider / Notifier / AsyncNotifier),新手学习曲线稍陡。

BLoC

BLoC(Business Logic Component)是严格分层的架构模式,将 UI 事件(Event)映射到状态(State),通过流(Stream)驱动 UI 更新。

// Event
abstract class CounterEvent {}
class IncrementEvent extends CounterEvent {}

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

// BLoC
class CounterBloc extends Bloc<CounterEvent, CounterState> {
  CounterBloc() : super(const CounterState(0)) {
    on<IncrementEvent>((event, emit) {
      emit(CounterState(state.count + 1));
    });
  }
}

优点:层次清晰,可测试性极高,适合大型团队协作。

缺点:样板代码多,简单功能也需要定义 Event/State 类,对小项目来说过重。

横向对比

维度ProviderRiverpodBLoC
上手难度⭐⭐⭐⭐⭐⭐⭐⭐⭐
类型安全一般优秀优秀
可测试性一般优秀极佳
适用规模小~中中~大大型团队
样板代码中等
异步支持需手动内置内置

我的选择

对于个人项目或小团队,我强烈推荐 Riverpod。它在简洁性和工程性之间取得了很好的平衡,Riverpod Generator(代码生成)出来后样板代码大幅减少,配合 AsyncValue 处理异步状态非常优雅。

如果你在面试或进入大公司团队,BLoC 是必须掌握的。它在可测试性和可追溯性上无可替代。