「画面が更新されない」「データをあちこちの画面で使いたい」
そんな悩みを解決してくれるのが Provider パッケージです。
目次
私はこれで挫折しました
数年前にFlutterを勉強したとき、Providerで挫折しました。
ChangeNotifierって何?notifyListeners()はなぜ必要?context.watchとcontext.readの違いは?
次々と知らない言葉が出てきて、意味がわからないまま進もうとして諦めてしまいました。
今回は 「なぜ必要なのか」から順番に 理解していこうと思います。
まず「Providerがない世界」を想像する
「月謝袋」のアプリを作っているとします。
「生徒一覧」のデータを、複数の画面で使いたい場面を考えてみます。
画面A(ホーム)
└─ 画面B(生徒リスト)
└─ 画面C(月謝管理)
└─ 画面D(スタンプ入力) ← ここでも生徒データが必要!
Providerがないと、こうなります。
// 画面Aから画面Bへデータを渡す
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => 画面B(students: students), // 渡す
),
);
// 画面Bから画面Cへ渡す
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => 画面C(students: students), // また渡す
),
);
// 画面Cから画面Dへ渡す
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => 画面D(students: students), // またまた渡す😩
),
);
これを 「バケツリレー」 と呼びます。
[生徒データ] → 画面A → 画面B → 画面C → 画面D
画面が増えるたびに、使いもしない画面にもデータを渡し続けなければなりません。とても面倒ですよね。
Providerを使うとどうなるの?
[生徒データ] ← アプリの「空中」に置く
↓ ↓ ↓
画面A 画面B 画面D ← どこからでも直接取り出せる!
バケツリレーが不要になります。
どの画面からでも、必要なときに直接データを取り出せます。
もう一つの大問題:「画面が更新されない」
Providerを使う前は、こんなことがありました。
// ボタンを押してデータを追加したのに画面が変わらない…
void addStudent(Student student) {
students.add(student); // データは追加されている
// でも画面は古いまま
}
データは更新されているのに、画面に反映されないという問題です。
(コンソールをみるとデータは確かに更新されています)
これを解決するために setState() を使う方法もありますが…
// setState()を使うやり方
setState(() {
students.add(student);
});
setState() は StatefulWidget の中でしか使えない ので、画面が増えるたびにあちこちに書かなければなりません。
Providerを使うと、この問題もスッキリ解決します。
Providerが解決してくれること(まとめ)
| 問題 | Providerなし | Providerあり |
|---|---|---|
| データの共有 | バケツリレーで全画面に渡す😩 | どこからでも直接取り出す✨ |
| 画面の更新 | setState()をあちこちに書く😩 | データ変更で自動更新✨ |
| コードの量 | どんどん増える😩 | スッキリする✨ |
Providerの仕組みをざっくり図解
┌─────────────────────────────┐
│ Provider(データの倉庫) │
│ ・生徒リスト │
│ ・月謝データ など │
└──────────┬──────────────────┘
│ データが変わったら自動通知
┌──────┼──────┐
↓ ↓ ↓
画面A 画面B 画面C
(自動更新)(自動更新)(自動更新)
Providerはアプリ全体のデータ倉庫 のようなものです。
データが変わると、そのデータを使っている画面が自動的に更新されます。
次回予告
次回は、Providerの核心である
ChangeNotifier(データの変化を知らせる仕組み)notifyListeners()(「変わったよ!」と叫ぶメソッド)
を解説します。
ここを理解すると、「なぜ画面が自動更新されるのか」がわかります!
このシリーズの全体構成
- 第1回(今回):Providerって何?なぜ必要なの?
- 第2回:ChangeNotifier と notifyListeners() を理解する
- 第3回:context.watch と context.read の違い
- 第4回:MultiProvider と MVVM設計でアプリを整理する
Flutter / Provider / 初心者 / アプリ開発
