State management is an integral aspect to handle for building responsive UI in Flutter. It is important to be careful about the state management approach you choose, as it directly affects the scalability, maintainability and performance of your app. Here’s a comparison and guide on using the three most popular options:
1. Provider – Simple & Officially Recommended
Provider is easy to learn and integrates well with the Flutter framework.
Example: Counter with ChangeNotifier
Dart:
class Counter extends ChangeNotifier { int value = 0; void increment() { value++; notifyListeners(); }
}
void main() { runApp(ChangeNotifierProvider(create: (_) => Counter(), child: MyApp()));
}
Consumer<Counter>( builder: (context, counter, _) => Text('${counter.value}'),
);
2. Riverpod – Robust, Testable, No Context Needed
Riverpod is a complete rewrite of Provider with better modularity and compile-time safety.
Example: Counter with StateNotifierProvider
Dart:
final counterProvider = StateNotifierProvider<Counter, int>((ref) => Counter());
class Counter extends StateNotifier<int> { Counter() : super(0); void increment() => state++;
}
final count = ref.watch(counterProvider);
3. Bloc – Scalable & Enterprise-Ready
Bloc is a predictable, event-driven architecture inspired by Redux.
Example: CounterBloc
Dart:
abstract class CounterEvent {}
class Increment extends CounterEvent {}
class CounterBloc extends Bloc<CounterEvent, int> { CounterBloc() : super(0) { on<Increment>((event, emit) => emit(state + 1)); }
}
Feature | Provider | Riverpod | Bloc |
Ease | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
Scalability | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
Boilerplate | Low | Medium | High |
Async/Stream | Basic | Strong support | Build-in |