Flutter状态管理概述 #

一、什么是状态 #

1.1 状态定义 #

状态是应用在某个时刻的数据快照,它决定了UI的显示内容。

dart
class Counter extends StatefulWidget {
  @override
  State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int _count = 0;
  
  void _increment() {
    setState(() {
      _count++;
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Count: $_count'),
        ElevatedButton(
          onPressed: _increment,
          child: Text('Increment'),
        ),
      ],
    );
  }
}

1.2 状态分类 #

类型 说明 示例
临时状态 Widget内部状态 动画状态、表单输入
应用状态 跨Widget共享状态 用户信息、购物车
持久状态 需要持久化的状态 用户设置、缓存数据

1.3 状态管理问题 #

  • 状态共享困难
  • 状态更新复杂
  • 代码耦合度高
  • 测试困难

二、状态管理方案 #

2.1 方案对比 #

方案 复杂度 适用场景
setState 简单 简单临时状态
InheritedWidget 中等 简单状态共享
Provider 中等 中小型应用
Riverpod 中等 现代应用
Bloc 复杂 大型应用
GetX 简单 快速开发

2.2 选择指南 #

text
简单应用 → setState
         ↓
小型应用 → Provider
         ↓
中型应用 → Riverpod
         ↓
大型应用 → Bloc

三、setState #

3.1 基本用法 #

dart
class Counter extends StatefulWidget {
  @override
  State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int _count = 0;
  
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('$_count'),
        ElevatedButton(
          onPressed: () => setState(() => _count++),
          child: Text('Add'),
        ),
      ],
    );
  }
}

3.2 适用场景 #

  • Widget内部简单状态
  • 不需要跨Widget共享
  • 快速原型开发

四、InheritedWidget #

4.1 基本用法 #

dart
class CounterInheritedWidget extends InheritedWidget {
  final int count;
  final VoidCallback increment;
  
  CounterInheritedWidget({
    required this.count,
    required this.increment,
    required Widget child,
  }) : super(child: child);
  
  static CounterInheritedWidget? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<CounterInheritedWidget>();
  }
  
  @override
  bool updateShouldNotify(CounterInheritedWidget oldWidget) {
    return count != oldWidget.count;
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CounterInheritedWidget(
      count: 10,
      increment: () {},
      child: ChildWidget(),
    );
  }
}

class ChildWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counter = CounterInheritedWidget.of(context);
    return Text('${counter?.count}');
  }
}

五、Provider #

5.1 安装 #

yaml
dependencies:
  provider: ^6.1.1

5.2 基本用法 #

dart
class Counter extends ChangeNotifier {
  int _count = 0;
  
  int get count => _count;
  
  void increment() {
    _count++;
    notifyListeners();
  }
}

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

class CounterWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('${context.watch<Counter>().count}'),
        ElevatedButton(
          onPressed: () => context.read<Counter>().increment(),
          child: Text('Add'),
        ),
      ],
    );
  }
}

六、Riverpod #

6.1 安装 #

yaml
dependencies:
  flutter_riverpod: ^2.4.9

6.2 基本用法 #

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

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

七、Bloc #

7.1 安装 #

yaml
dependencies:
  flutter_bloc: ^8.1.3

7.2 基本用法 #

dart
abstract class CounterEvent {}
class Increment extends CounterEvent {}

class CounterBloc extends Bloc<CounterEvent, int> {
  CounterBloc() : super(0) {
    on<Increment>((event, emit) => emit(state + 1));
  }
}

class CounterWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (_) => CounterBloc(),
      child: Column(
        children: [
          BlocBuilder<CounterBloc, int>(
            builder: (context, count) => Text('$count'),
          ),
          ElevatedButton(
            onPressed: () => context.read<CounterBloc>().add(Increment()),
            child: Text('Add'),
          ),
        ],
      ),
    );
  }
}

八、总结 #

8.1 方案选择 #

场景 推荐方案
简单状态 setState
小型应用 Provider
现代应用 Riverpod
大型应用 Bloc

8.2 下一步 #

让我们深入学习 StatefulWidget

最后更新:2026-03-28