Flutter State Management

Managing state in Flutter apps with setState, Provider, and Riverpod.

setState - Local State

Stateful Widget
class Counter extends StatefulWidget {
  @override
  _CounterState createState() => _CounterState();
}

class _CounterState extends State {
  int _counter = 0;

  void _increment() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Text("$_counter");
  }
}

Provider - Recommended

Install Provider
dependencies:
  provider: ^6.0.0

Create Model
class Counter with ChangeNotifier {
  int _count = 0;
  int get count => _count;

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

Provide
ChangeNotifierProvider(
  create: (context) => Counter(),
  child: MyApp(),
)

Consume
Consumer<Counter>(
  builder: (context, counter, child) {
    return Text("${counter.count}");
  }
)

Read value
context.read<Counter>().increment();

Watch value
final counter = context.watch<Counter>();

Riverpod - Modern

Install Riverpod
dependencies:
  flutter_riverpod: ^2.0.0

Create Provider
final counterProvider = StateProvider((ref) => 0);

Setup ProviderScope
void main() {
  runApp(
    ProviderScope(
      child: MyApp(),
    ),
  );
}

ConsumerWidget
class Home extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterProvider);
    return Text("$count");
  }
}

Update state
ref.read(counterProvider.notifier).state++;

BLoC Pattern

Install flutter_bloc
dependencies:
  flutter_bloc: ^8.0.0

Create Event
abstract class CounterEvent {}
class Increment extends CounterEvent {}

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

Provide BLoC
BlocProvider(
  create: (context) => CounterBloc(),
  child: MyApp(),
)

BlocBuilder
BlocBuilder<CounterBloc, int>(
  builder: (context, state) {
    return Text("$state");
  }
)

Comparison

setState
✓ Simple, built-in
✓ Good for local state
✗ Not scalable
✗ No separation of concerns

Provider
✓ Recommended by Flutter team
✓ Simple API
✓ Good performance
✓ Easy to learn

Riverpod
✓ Modern, compile-safe
✓ No BuildContext needed
✓ Better testing
✗ Steeper learning curve

BLoC
✓ Predictable state
✓ Great for complex apps
✗ More boilerplate
✗ Harder to learn