0
0
FlutterHow-ToBeginner · 4 min read

How to Use Riverpod in Flutter: Simple Guide with Examples

To use Riverpod in Flutter, first add the flutter_riverpod package, then create providers to manage state and consume them in widgets using ConsumerWidget or hooks. Riverpod offers a simple, safe way to manage app state without context dependencies.
📐

Syntax

Riverpod uses providers to expose state or objects. You define a provider, then read or watch it inside widgets.

  • final myProvider = Provider<Type>((ref) => value); defines a provider.
  • ConsumerWidget or Consumer widgets listen to providers.
  • ref.watch(myProvider) reads the current value reactively.
dart
import 'package:flutter_riverpod/flutter_riverpod.dart';

final greetingProvider = Provider<String>((ref) {
  return 'Hello Riverpod!';
});

class MyWidget extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final greeting = ref.watch(greetingProvider);
    return Text(greeting);
  }
}
Output
A Text widget displaying: Hello Riverpod!
💻

Example

This example shows a counter app using Riverpod to manage the counter state. It demonstrates defining a StateProvider, reading and updating state inside a ConsumerWidget.

dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: CounterScreen());
  }
}

class CounterScreen extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterProvider);
    return Scaffold(
      appBar: AppBar(title: Text('Riverpod Counter')),
      body: Center(child: Text('Count: $count', style: TextStyle(fontSize: 24))),
      floatingActionButton: FloatingActionButton(
        onPressed: () => ref.read(counterProvider.notifier).state++,
        child: Icon(Icons.add),
      ),
    );
  }
}
Output
App screen with text 'Count: 0' and a button; pressing button increments count displayed.
⚠️

Common Pitfalls

Common mistakes when using Riverpod include:

  • Not wrapping the app with ProviderScope, which is required to use providers.
  • Using ref.read instead of ref.watch inside build methods, which prevents UI updates.
  • Mutating state directly instead of using the provider's state setter.
dart
/* Wrong: Not wrapping app with ProviderScope */
void main() {
  runApp(MyApp()); // Missing ProviderScope
}

/* Correct: Wrap with ProviderScope */
void main() {
  runApp(ProviderScope(child: MyApp()));
}

/* Wrong: Using ref.read in build to watch state */
final count = ref.read(counterProvider); // Won't update UI

/* Correct: Use ref.watch to rebuild on changes */
final count = ref.watch(counterProvider);
📊

Quick Reference

Here is a quick summary of common Riverpod providers and usage:

Provider TypePurposeExample
ProviderExpose a value or objectfinal greeting = Provider((ref) => 'Hi');
StateProviderManage simple mutable statefinal counter = StateProvider((ref) => 0);
FutureProviderAsync data from a Futurefinal data = FutureProvider((ref) => fetchData());
StreamProviderAsync data from a Streamfinal stream = StreamProvider((ref) => streamData());

Key Takeaways

Always wrap your Flutter app with ProviderScope to enable Riverpod.
Define providers to hold state or objects and consume them with ref.watch inside ConsumerWidget.
Use StateProvider for simple mutable state and update it via ref.read(provider.notifier).state.
Avoid using ref.read inside build methods when you want UI to update on state changes.
Riverpod provides a safe, testable, and context-independent way to manage state in Flutter.