Flutter 状态管理
状态管理方案对比
| 方案 | 复杂度 | 适用场景 |
|---|---|---|
| setState | 低 | 组件内简单状态 |
| InheritedWidget | 中 | 跨组件数据传递 |
| Provider | 中 | 中小型应用 |
| Riverpod | 中高 | 类型安全、可测试 |
| Bloc | 高 | 大型应用、复杂业务 |
Provider
基础使用
dart
import 'package:provider/provider.dart';
// 1. 定义状态
class Counter with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
// 2. 提供状态
void main() {
runApp(
ChangeNotifierProvider(
create: (_) => Counter(),
child: MyApp(),
),
);
}
// 3. 消费状态
class CounterWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 监听变化
final counter = context.watch<Counter>();
return Column(
children: [
Text('Count: ${counter.count}'),
ElevatedButton(
// 只读取,不监听
onPressed: () => context.read<Counter>().increment(),
child: Text('Increment'),
),
],
);
}
}多 Provider
dart
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => UserModel()),
ChangeNotifierProvider(create: (_) => CartModel()),
Provider(create: (_) => ApiService()),
],
child: MyApp(),
)Riverpod
基础使用
dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
// 1. 定义 Provider
final counterProvider = StateNotifierProvider<CounterNotifier, int>((ref) {
return CounterNotifier();
});
class CounterNotifier extends StateNotifier<int> {
CounterNotifier() : super(0);
void increment() => state++;
void decrement() => state--;
}
// 2. 使用 ProviderScope
void main() {
runApp(
ProviderScope(child: MyApp()),
);
}
// 3. 消费状态
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'),
),
],
);
}
}异步 Provider
dart
final userProvider = FutureProvider<User>((ref) async {
final response = await http.get('https://api.example.com/user');
return User.fromJson(jsonDecode(response.body));
});
class UserWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final userAsync = ref.watch(userProvider);
return userAsync.when(
loading: () => CircularProgressIndicator(),
error: (err, stack) => Text('Error: $err'),
data: (user) => Text('Hello, ${user.name}'),
);
}
}Bloc
基础使用
dart
import 'package:flutter_bloc/flutter_bloc.dart';
// 1. 定义 Event
abstract class CounterEvent {}
class IncrementEvent extends CounterEvent {}
class DecrementEvent extends CounterEvent {}
// 2. 定义 State
class CounterState {
final int count;
CounterState(this.count);
}
// 3. 定义 Bloc
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterState(0)) {
on<IncrementEvent>((event, emit) {
emit(CounterState(state.count + 1));
});
on<DecrementEvent>((event, emit) {
emit(CounterState(state.count - 1));
});
}
}
// 4. 提供 Bloc
BlocProvider(
create: (_) => CounterBloc(),
child: CounterWidget(),
)
// 5. 消费 Bloc
class CounterWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) {
return Column(
children: [
Text('Count: ${state.count}'),
ElevatedButton(
onPressed: () => context.read<CounterBloc>().add(IncrementEvent()),
child: Text('Increment'),
),
],
);
},
);
}
}Cubit(简化版 Bloc)
dart
class CounterCubit extends Cubit<int> {
CounterCubit() : super(0);
void increment() => emit(state + 1);
void decrement() => emit(state - 1);
}
// 使用
BlocBuilder<CounterCubit, int>(
builder: (context, count) => Text('Count: $count'),
)状态管理选择
简单应用 复杂应用
│ │
▼ ▼
setState ──▶ Provider ──▶ Riverpod ──▶ Bloc
│
▼
GetX (争议较多)面试要点
- Provider 原理:InheritedWidget + ChangeNotifier
- Riverpod 优势:编译时安全、无 BuildContext 依赖
- Bloc 模式:Event -> Bloc -> State 单向数据流
- 选型建议:根据团队经验和项目规模选择