0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Flutter Riverpod】NotifierProvider vs StateNotifierProvider の違いと使い分け徹底解説!

Last updated at Posted at 2025-07-31

はじめに

本記事の目的

  • 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 を使うことをおすすめします!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?