【学習メモ：Flutter入門編】 Riverpodの使い方

これから「Flutter」を勉強していこうと思っている人向けには「メモ」程度で参照してみてください。

■ 「Riverpod」とは？
私の現時点の知識では詳しく説明はできませんが、入力文字列の「状態管理」を行うためのライブラリだということ。

もう少し詳しい事は下記の記事を参照してみてください。

https://zenn.dev/riscait/books/flutter-riverpod-practical-introduction/viewer/what-is-riverpod

https://qiita.com/taisei_dev/items/4c9d9572a56051a1d51f

■ 「Riverpod」使うための定義
「pubspec.yaml」に以下の定義を追加する必要がある。

```diff
dependencies:
+ flutter_riverpod:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.6
```

保存するとVSCodeが、自動的に必要なパッケージをダウンロードしてくれる模様。

■ 「Riverpod」のパッケージを利用するための定義
必要なimport宣言として以下の定義を追加。

`import 'package:flutter_riverpod/flutter_riverpod.dart';`

また、アプリ（MaterialApp）の登録方法も修正が必要。

```diff
  final app = MaterialApp(
    home: Scaffold(
      body: Center(
        child: col
      ),
    )
  );

+ final scope = ProviderScope(child: app);

- runApp(app);
+ runApp(scope);
```

上記修正により「Riverpod」の仕組みを利用する為の下準備が完了します。

■ 「Riverpod」の仕組み
登場する3つの役割についてそれぞれ説明します。

### Provider
* 変更させたいデータ本体（State）を管理する役割

### ConsumerWidget
* 「Provider」が管理しているデータ本体（State）を監視する役割
* データ本体（State）を監視するできるようにするために必要な鍵（ref）を持っている。（イメージです）

### Notifier
* 「ConsumerWidget」が保持している鍵（ref）を借りて、データ本体（State）の内容を変更する役割

:::note info
3つの役割のイメージについては、記事の最後に記載している私が学習の参考にさせていただいている動画を参照した方がイメージが湧きやすいと思いますので、気になる人は参照する事をお勧めいたします。
:::

■ サンプルコード
私がお試しで作成したコードの一部を抜粋して記載しておきます。

### Provider
```
final checkProvider = StateProvider<String>(
  (ref) {
    return '変更前';
  }
);
```

### ConsumerWidget
```
class RiverpodTest extends ConsumerWidget {
  const RiverpodTest({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // データを監視
    final check = ref.watch(checkProvider);

    // 文字列①
    final text1 = Text(
      check,
      style: const TextStyle(
        color: Colors.yellow,
        fontSize: 20
      ),
    );

    // 文字列②
    final text2 = Text(
      check,
      style: const TextStyle(
        color: Colors.cyan,
        fontSize: 20
      ),
    );

    // 文字列③
    final text3 = Text(
      check,
      style: const TextStyle(
        color: Colors.red,
        fontSize: 20
      ),
    );

    final buttonA = ElevatedButton(
      onPressed: () => clickA(ref),
      child: Text('Click A'),
    );

    final buttonB = ElevatedButton(
      onPressed: () => clickB(ref),
      child: Text('Click B'),
    );

    final buttonC = ElevatedButton(
      onPressed: () => clickC(ref),
      child: Text('Click C'),
    );

    final col1 = Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        text1,
        text2,
        text3,
    ]);

    final col2 = Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        buttonA,
        buttonB,
        buttonC,
    ]);

    final row = Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        col1,
        col2,
    ]);

    final con = Container(
        width: 300,
        height: 200,
        child: row,
        alignment: Alignment.center,
        decoration: BoxDecoration(
          color: Colors.black,
          borderRadius: BorderRadius.circular(20),
        ),
    );

    return con;
  }
}
```

### Notifier
```
clickA (WidgetRef ref) {
  final notifier = ref.read(checkProvider.notifier);
  notifier.state = '変更後【 clickA 】';
}

clickB (WidgetRef ref) {
  final notifier = ref.read(checkProvider.notifier);
  notifier.state = '変更後【 clickB 】';
}

clickC (WidgetRef ref) {
  final notifier = ref.read(checkProvider.notifier);
  notifier.state = '変更後【 clickC 】';
}
```

実際の動作画面のキャプチャも併せて添付しておきます。
やっていることは、ただ色分けされた「変更前」の文字列が、各ボタンをクリックした際に、「変更後」の文字列の最後に、それぞれのボタンごとに呼び出されている関数名を記載するようにしているだけです。

今回のテストで確認したい動作としては、ボタンクリックお後に **各「変更前」の文字列が「同時」に変更されていること** です！

【ボタンクリック前】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755252/564f8caa-0ecb-1074-30f0-647f26fd003e.png)

【Click A】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755252/d4b62549-db72-5c12-3a05-478261507c0d.png)

【Click B】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755252/ce15922c-06bb-b5fc-8300-6c5cefa95ca7.png)

【Click C】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755252/fedc891c-2850-b0a3-8bb6-a6da41d49ae9.png)

# 最後に
Flutter（Dart言語）に関する最低限の情報を「学習メモ」としてまとめてみました。
内容に誤りがありそうであれば、遠慮なくご指摘いただけますと幸いです。

【学習の参考にした動画】
素敵な解説動画の作成ありがとうございます。
本記事の内容より。動画を見た方が解りやすいと思います。

https://www.youtube.com/watch?v=w2xo2FjDUNQ&list=PLY1cxwSQf6nz6zo2Y_UJlDjGOpASAO4hd&index=9