Riverpod
Riverpod is a Reactive State-Management and Dependency Injection Framework library on Flutter. Nov 5, 2021, the release date of version 1.0.0 has come, and modified some features. In this article, I'll try to describe how you would manage the state by Riverpod with simple application.
What is Riverpod?
- No more
ProviderNotFoundException
- Provider inspires Riverpod but solves some of its key issues
- No dependency on Flutter
Goal
Let's make a simple app that counts number per pushing a button.
Environment
dependencies:
flutter:
sdk: flutter
riverpod: ^1.0.0
flutter_hooks: ^0.18.0
hooks_riverpod: ^1.0.0
1. Update state with StateNotifierProvider
Use StateNotifierProvider
, StateNotifier
, HookConsumerWidget
to update and read state.
2. Import packages
import 'package:flutter/material.dart';
import 'package:riverpod/riverpod.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
3. Define countStateProvider variable with StateNotifierProvider
StateNotifierProvider
is combined with StateNotifier
.
StateNotifierProvider class - riverpod library - Dart API
final countStateProvider =
StateNotifierProvider<CountState, int>((ref) => CountState(0));
4. Set up CountState class with StateNotifier
StateNotifier
is an observable class that stores a single immutable state. At first, create CountState class extended StateNotifier class.
class CountState extends StateNotifier<int> {
CountState(int count) : super(count);
void increment() => state = state + 1;
}
StateNotifier is designed to be subclassed. You first need to give an initial value to the super constructor. In the above, CountState class receives the count argument, and then passes it to the super constructor.
CountState(int count) : super(count);
The next shows the published method to allow other objects modify to modify the counter.
void increment() => state = state + 1;
It is possible to define multiple methods in StateNotifier class.
void increment() => state++;
void decrement() => state--;
5. ProviderScope on Riverpod
All applications dealing with Riverpod must contain a ProviderScope at the root of your widget tree. Thus, let's wrap MyApp class defined next chapter by ProviderScope.
void main() {
runApp(ProviderScope(
child: MyApp(),
));
}
6. MyAPP with HookConsumerWidget
Let's make a MaterialApp in MyApp class extending HookConsumerWidget, the alternative of HookWidget, released after version 1.0.0.
class MyApp extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final int count = ref.watch(countStateProvider);
return MaterialApp(
home: Scaffold(
body: Center(child: Text('$count')),
floatingActionButton: FloatingActionButton(
onPressed: () {
ref.read(countStateProvider.notifier).increment();
},
),
),
);
}
}
To watch the state in countStateProvider, define the count variable with ref.watch(), replaced from useProvider on the previous version.
Widget build(BuildContext context, WidgetRef ref) {
final int count = ref.watch(countStateProvider);
Add ref.read() to call increment() function in CountState for when pressing floatingActionButton.
onPressed: () {
ref.read(countStateProvider.notifier).increment();
},
7. Whole code
import 'package:flutter/material.dart';
import 'package:riverpod/riverpod.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
final countStateProvider =
StateNotifierProvider<CountState, int>((ref) => CountState(0));
class CountState extends StateNotifier<int> {
CountState(int count) : super(count);
void increment() => state = state + 1;
}
void main() {
runApp(ProviderScope(
child: MyApp(),
));
}
class MyApp extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final int count = ref.watch(countStateProvider);
return MaterialApp(
home: Scaffold(
body: Center(child: Text('$count')),
floatingActionButton: FloatingActionButton(
onPressed: () {
ref.read(countStateProvider.notifier).increment();
},
),
),
);
}
}
Top comments (0)