条件分岐でウィジェットを表示したい

# ご挨拶
ども、ぺんまるです。
最近は暑くてやる気がでないです。
クーラーはつけてるのにやる気が出ないってなんなんですかね…

それは置いといて、今回も作業中にちょっと行き詰まったというか、調べたことの備忘録を書きます。


# この記事の対象者
- flutterとdartの初学者(カウンターアプリなどは作成してみた人)

# 目的
コードを書いていく中でウィジェットを条件に応じて表示させたいなどがあると思います。
例えば、countという変数があってボタンを押すたびにこのcount変数がインクリメントしていく、そしてある一定の値になるとカウントが〇〇を超えました！みたいなTextウィジェットを表示させたいなど…

今回はその条件によって表示させるウィジェットを変えることを目的として書いていきます。

# 解決方法
## if文
まずこのようなコードを作ります。
```dart:sample.dart
Widget build(BuildContext context, WidgetRef ref) {
    final counter = useState(0);
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('猫が${counter.value.toString()}匹',
        style: const TextStyle(
          fontSize: 40,
          fontWeight: FontWeight.bold,
        ),),
        ElevatedButton(
          onPressed: () => counter.value++,
          child: const Text('押下'),)
      ],
    );
  }
```
hooksを使っていますがcounterは初期値が0の変数でcounter.value++は数字が1ずつ上がるものだと思ってください
ちなみにuseStateは状態を監視するので、数字が上がるたびに再描画されます。
画面を表示するとこうなります。
<img width="50%"
src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556254/e4ac348c-d875-b3ee-d9d1-c7db0c16abd0.png">


そしてこのコードをifで条件分岐すると以下のコードになります
```dart:sample.dart
 Widget build(BuildContext context, WidgetRef ref) {
    final counter = useState(0);
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        if (counter.value > 0)
          Text(
            '猫が${counter.value.toString()}匹',
            style: const TextStyle(
              fontSize: 40,
              fontWeight: FontWeight.bold,
            ),
          ),
        if (counter.value <= 0)
          const Text(
            '猫がいない',
            style: TextStyle(
              fontSize: 40,
              fontWeight: FontWeight.bold,
            ),
          ),
        ElevatedButton(
          onPressed: () => counter.value++,
          child: const Text('押下'),
        )
      ],
    );
  }
}
```
そして画面はこうなります(画質悪くておもろい)

<img width="50%"
src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556254/f81f8016-bdb4-5841-ecf3-a3d954f705f4.gif">

これはTextの親ウィジェットがColumnであり、children以下はList<Widget>を指定するため、コレクションifが使えるとのことです。

Dart2.3以降ではifをコレクション内で使えるらしいです
コレクションとは
`List`,`Set`,`Map`のことです。

# 三項演算子
先ほどのifではコレクション内でしか使えないとのこと
例えば、Containerでは指定するのがコレクションではないため、ifは使えません
Container内で条件分岐するには三項演算子を使いましょう
ってことで以下コードです。
```dart:sample.dart
@override
  Widget build(BuildContext context, WidgetRef ref) {
    final counter = useState(0);
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Container(
          color: counter.value > 0 ? Colors.deepOrange : Colors.cyanAccent,
          child: counter.value > 0
              ? Text(
                  '猫が${counter.value.toString()}匹',
                  style: const TextStyle(
                    fontSize: 40,
                    fontWeight: FontWeight.bold,
                  ),
                )
              : const Text(
                  '猫がいない',
                  style: TextStyle(
                    fontSize: 40,
                    fontWeight: FontWeight.bold,
                  ),
                ),
        ),
        ElevatedButton(
          onPressed: () => counter.value++,
          child: const Text('押下'),
        )
      ],
    );
  }
}

```
今回はContainerでTextをラップしました。
colorプロパティをcounterが10より大きい場合は色も変えるようにしました。
ちなみに三項演算子だとコレクション内でも使えます。


<img width="50%"
src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556254/1525cd56-7723-ca71-3eed-4d379aa72c62.gif>


# まとめ
ウィジェットを条件分岐させたい場合は

- コレクション(ColumやRowなど)の場合はif(switchも使えるらしい)
- 条件によって表示させるウィジェットが2つのパターンであれば三項演算子
    - Containerなどのコレクション以外ではこちら
    - コレクションでも使える

if文はステートメントなので値を返す、返さないと不定なため使えなかったようです。
一方三項演算子は式なので、必ず値を返すから使えるそうです
もちろんウィジェットを返さないとエラーは出ますが

ちなみに他の方法としては
- 条件を書いた関数を定義して呼び出す
- 即時関数を使う
などがあるそうです

関数を定義する方法は条件が複雑な場合はそのように書いた方が可読性があっていいと思います。
即時関数は()の数が多くて個人的にはおすすめしないです。

最後に個人的にはどちらでも使える三項演算子が使い慣れているのですが、List形式だとifの方がみやすい感じはしますね
公式推奨らしいので今後はifを使った方がいいかもしれません

ここまで読んで頂きありがとうございました。


# 参考にさせていただいた記事
- https://zenn.dev/ryu2021/articles/3d2d0345445435
- https://qiita.com/hk0503/items/01fd5e1303daf8db1c1a