FlutterでGetXを使って状態管理

# インストール
`pubspec.yaml`ファイルを開き、以下のコードを探す。
```yaml:pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
```

下に、`get: ^4.6.5`を追加し、ファイルを保存。
（他に追加しているものがあればその下でも可。とりあえず、dependencies:flutter:の中に）

```diff_yaml:pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
+   get: ^4.6.5

```
注意：バージョンは公式のバージョンを確認すること

https://pub.dev/packages/get/versions

パッケージのインストール。
VSCodeでは自動で追加されるらしい？（Cursorでは別途必要だった。）
```terminal:terminal
flutter pub get
```


# コントローラー
コントローラーとは、flutterで状態管理を行うためのクラス。
GetXでは、**GetxController**を拡張してコントローラーを使う。
コントローラーはインスタンス化して使う（後述）

```dart:コントローラーの定義
// GetxControllerから拡張したコントローラーを作成
class CounterController extends GetxController {
  final count = 0.obs; // Observable変数を宣言
  // カウントアップ
  increment() => count++;
}
```
このコントローラ内でカウンターなどの状態を管理する。


# Observable変数
`Observable`＝観測可能な という意味で、**値の変更を監視できる特殊な変数**
状態管理をするときに使う。**Rx**と呼ばれることもある。
Observable変数の値が変更された際に、それをUIに通知するために使われる。
例えば、値が更新されると、自動でUIを更新したいときに使う。
## リアクティブなデータ型
Observable変数には様々なデータ型がある。
「リアクティブ（= 反応する、反応性のある）」とは、データの変更が発生した際に、関連するUIやロジックが自動的に反応し、更新されること。
| 型 | 説明 |
|:-:|:-:|
| `RxString`  | リアクティブな文字列  |
| `RxInt`  | リアクティブな整数  |
| `RxDouble`  |  リアクティブな倍精度浮動小数点数 |
| `RxBool`  | リアクティブなブール値  |
| `RxList`  |  リアクティブなリスト |
|  `RxMap` | リアクティブなマップ  |
| `RxSet`  | リアクティブなセット  |
| `Rx<T>`  | 任意のクラスTのリアクティブなインスタンス  |

※ 個人的にピンとこなかったもの
**リスト**はJSでは配列、**マップ**はオブジェクト、**セット**は重複した値を持たない配列のイメージ(JSにもセットはあったらしい。ほぼ使ってなかった。。。)



## 変数の宣言
公式ドキュメントの記載部分↓

https://github.com/jonataslaw/getx/blob/master/documentation/ja_JP/state_management.md#%E3%83%AA%E3%82%A2%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96%E3%81%AA%E5%A4%89%E6%95%B0%E3%81%AE%E5%AE%A3%E8%A8%80

定義の方法は3つあるが、ここでは一番シンプルなものを
**変数の末尾に .obs を付ける**
```dart
final count = 0.obs;
// 公式ではvarを使ってたが、finalを使うほうが無難とされる（詳細は省く）
```
初期値は設定しておくことが推奨されている。
上記のコードでは、dartが型を推論して、
**変数名`count`はRxInt 型の変数**
と認識される。ときには明示的に型宣言することも必要なのかも:thinking:

| 型 | 説明 | 具体例 |
|:-:|:-:|:-:|
| `RxString` | 文字列 | `var greeting = 'Hello'.obs;` |
| `RxInt` | 整数 | `var counter = 0.obs;` |
| `RxDouble` | 倍精度浮動小数点数 | `var rating = 3.5.obs;` |
| `RxBool` | ブール値 | `var isChecked = false.obs;` |
| `RxList` | リスト | `var items = <String>[].obs;` |
| `RxMap` | マップ | `var info = {'name': 'GetX'}.obs;` |
| `RxSet` | セット | `var names = <String>{}.obs;` |
| `Rx<T>` | 任意のクラスTのインスタンス | `var user = User().obs;` <br/>※ ここではUserクラス |

# 変数をウィジェット内で使う
コントローラーを使って宣言した変数を使うためには、**コントローラーのインスタンス化**が必要。
→GetXの依存関係注入システムに登録、という作業。簡単に言うといろんなところから呼べるようにするってこと。

https://github.com/jonataslaw/getx/blob/master/documentation/ja_JP/dependency_management.md


## コントローラーのインスタンス化
`Get.put()`で、コントローラーの新しいインスタンスを作成できる。

```dart
class SimpleGetXApp extends StatelessWidget {
  // コントローラーのインスタンス化
  // controller型の変数cに、CounterControllerクラスのインスタンスを代入
  final CounterController c = Get.put(CounterController());

  @override
  Widget build(BuildContext context) {

  // 省略・・・
  ```
## 変更を検知
**`Obx`ウィジェット**を使用する。
```
obx(()=>  )
```
これで囲ってあげることで、変更があった場合に更新される

以下はcountに変更があったときにObxウィジェット内のTextウィジェットが更新される。

```dart
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          // Obxは、監視対象の変数を受け取り、変更があったときに自動的に画面を更新する
          child: Obx(() => Text("${c.count.value}")),
        ),
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
          // カウントアップ
          onPressed: c.increment,
```

`${c.count.value}`で値を受け取る。
`c.increment`で、メソッドを呼び出す。

# 参考
https://zenn.dev/sae_eng/articles/dcf7497117fb2b

https://yamochun-dev.cloud/dev/flutter/about-getx/

https://youtu.be/wtHBsvj2QKA?si=Bbt3U5t1ckU2_MXo