ToDoリストを作ってみよう

Todoアプリ作成の前に

StateNotifierとNotifierについて

Todoモデルの作成

1つのタスク(Todo)を表すクラスを定義します。

イミュータブルにすることで、状態を安全に管理できます。

class Todo {
  final String id; //TodoのID
  final String title; //Todoのタイトル
  final bool isCompleted; //完了状態
// (1)
  Todo({          //コンストラクタ
    required this.id, //インスタンス作成時にrequiredが必要
    required this.title,
    required this.isCompleted,
  });
// (2)
  Todo copyWith({
    String? title,
    bool? isCompleted,
  }) {
    return Todo(
      id: id,             //IDは常に同じ
      title: title ?? this.title, //新しい値か既存の値
      isCompleted: isCompleted ?? this.isCompleted,
    );
  }
}

(1) 使用例

final todo = Todo(
  id: '1',
  title: '買い物に行く',
  isCompleted: false,
);

(2) 使用例

final todo = Todo(id: '1', title: '掃除', isCompleted: false);

// タイトルだけ変更
final updated1 = todo.copyWith(title: '大掃除');

// 完了状態だけ変更
final updated2 = todo.copyWith(isCompleted: true);

// 両方変更
final updated3 = todo.copyWith(
  title: '洗濯',
  isCompleted: true,
);

このメソッドの目的

Notifierクラスの定義

class TodoNotifier extends Notifier<List<Todo>> {.  //<List,Todo>>型の状態を管理
  @override
  List<Todo> build() {. //アプリ起動時やProviderが初めて読み込まれた時に呼ばれる
    return []; // 初期状態は空のリスト
  }

// (1)
  void add(String title) { 
    state = [
      ...state,  //スプレッド演算子
      Todo(
        id: DateTime.now().toString(),  //現在時刻をIDに使用
        title: title,
        isCompleted: false,
      ),
    ];
  }

// (2)
  void toggle(String id) {. //完了状態の切り替え
    state = state
        .map((todo) => todo.id == id
            ? todo.copyWith(isCompleted: !todo.isCompleted)//対象のtodoは反転
            : todo) //それ以外はそのまま
        .toList();
  }
// (3) 
  void remove(String id) { //Todo削除
    state = state.where((todo) => todo.id != id).toList();
  }
}

(1) 動作の流れ:

  1. ...stateで既存のTodo全てをコピー