見出し画像

[Flutter] Stateless vs Stateful

お久しぶりです。
6月もそろそろ終わりそうですが、天気は未だ不安定ですね。

今日は以下2点についてまとめていこうと思います。
1. パフォーマンスについて
2. StateLess内で動的に変化させる場合

リファレンス

Stateless
Stateful
checkBox
ListView
ListTile

そもそもStatelessとStatefulとは

class内で、動的に変数を変化させたい場合は、Stateful
静的に使う場合は、Statelessを使う。程度の説明で済ませます。他にもわかりやすい説明をしてくださってる記事がたくさんありますので。

1. パフォーマンスについて

statefulを用いて、画面の更新が発生する場合、ページ全体を更新するか。もしくは、必要な部分だけを更新するかで差が出てきますので、後者の方を取るのがベターとされてます。(バッテリーの消費量が多いアプリは嫌われますわな)

2. Stateless内で動的に変化させる場合

1を踏まえて、例えば、以下の構図になった場合、

スクリーンショット 2020-06-26 12.30.54

この場合は、Stateful widget内で、setStateを使って変化させてあげればいいと思います。しかし、Stateful Widget内の結果を使って、親の階層に変数を渡したい場合、どうすればいいか。

スクリーンショット 2020-06-26 12.31.11

Statefulな子widget内で定義していた変数を一度、親Widget内に持っていきます。そして、Statefulに変更し動的に変化できるようにします。そうすると、Statefulな子widgetはStatefulである必要はなくなるので、以下のようになります。

スクリーンショット 2020-06-26 12.31.24

これで、二つの子Widgetは、親の変更に伴い、変化できるようになります。

しかし、ここで問題なのが、もともとStatefulな子widgetが動的に変化できないままです。

もともと動的に変化できるため、コールバック関数を持ったプロパティだと思いますので、その場合、親Widgetで関数を定義し、子Widgetを呼ぶ際に、関数も引数としてセットしてあげれば、動作します。

概要は以下

class Parent extends StatefulWidget {
 @override
 _ParentState createState() => _ParentState();
}

class _ParentState extends State<Parent> {
 bool isChecked = false;
 void childFunction(){
   setState(() {
           //必要な関数
         });
 }

 @override
 Widget build(BuildContext context) {
   return ListTile(
     title: Text(
       '親',
     ),
     trailing: Child(
       state: isChecked,
       stateFunction: childFunction,
     ),
   );
 }
}

class Child extends StatelessWidget {
 final bool state;
 final Function stateFunction;

 Child({this.state, this.stateFunction});

 @override
 Widget build(BuildContext context) {
   return Checkbox(
     value: state,
     onChanged: stateFunction,
   );
 }
}


所感

改めて、Stateless内でも動的に変更できるのは、コールバックがあった時だけなのかどうかは今後使っていく中で考えていこうと思います。

間違い等あれば教えてください。

ではまた。

この記事が気に入ったらサポートをしてみませんか?