はじめに
本記事の目的
- Riverpodでよく使われる StateNotifierProvider と NotifierProvider の違いを整理
- どちらを選ぶべきか、どう書き換えるべきかを明確にする
Riverpodとは(簡潔に)
-
RiverpodはFlutter向けのモダンな状態管理ライブラリ
-
Context不要、型安全、テストしやすい
-
v2以降で NotifierProvider が正式導入された
例のコード
ToDoモデルクラス
class ToDo {
final int id;
final String title;
final bool isCompleted;
ToDo({required this.id, required this.title, this.isCompleted = false});
ToDo copyWith({String? title, bool? isCompleted}) {
return ToDo(
id: id,
title: title ?? this.title,
isCompleted: isCompleted ?? this.isCompleted,
);
}
}
実装:StateNotifierProvider版
class ToDoListViewModel extends StateNotifier<List<ToDo>> {
ToDoListViewModel() : super([]);
int _idCounter = 0;
void add(String title) {
final todo = ToDo(id: _idCounter++, title: title);
state = [...state, todo];
}
void toggle(int id) {
state = [
for (final todo in state)
if (todo.id == id) todo.copyWith(isCompleted: !todo.isCompleted) else todo
];
}
void remove(int id) {
state = state.where((todo) => todo.id != id).toList();
}
}
final toDoListProvider = StateNotifierProvider<ToDoListViewModel, List<ToDo>>(
(ref) => ToDoListViewModel(),
);
実装:NotifierProvider版
class ToDoListViewModel extends Notifier<List<ToDo>> {
int _idCounter = 0;
@override
List<ToDo> build() => [];
void add(String title) {
final todo = ToDo(id: _idCounter++, title: title);
state = [...state, todo];
}
void toggle(int id) {
state = [
for (final todo in state)
if (todo.id == id) todo.copyWith(isCompleted: !todo.isCompleted) else todo
];
}
void remove(int id) {
state = state.where((todo) => todo.id != id).toList();
}
}
final toDoListProvider =
NotifierProvider<ToDoListViewModel, List<ToDo>>(ToDoListViewModel.new);
並べて比較
比較項目 | StateNotifier |
Notifier |
---|---|---|
状態初期化 | コンストラクタ | build() |
ref の注入 |
自分で constructor に渡す |
自動で build() に注入される |
APIの新しさ | 旧スタイル(Riverpod 1.x) | 新スタイル(2.x以降) |
どちらを使うべき?
状況 | 推奨プロバイダー |
---|---|
既存プロジェクトを保守中 | StateNotifierProvider |
新しく状態クラスを作るなら | ✅ NotifierProvider
|
ref.watch() をViewModel内で使いたい |
✅ NotifierProvider
|
非同期処理も含めたい(API取得など) |
AsyncNotifierProvider を検討 |
まとめ
-
NotifierProvider は今後のRiverpodで 推奨される新しいクラスベースの状態管理
-
StateNotifierProvider は従来の実績ある手法だが、NotifierProvider の方が簡潔で保守性が高い
-
今後の新規開発では、基本的に NotifierProvider を使うことをおすすめします!