😶‍🌫️

【面接で聞かれた!】FlutterのStateful Widgetのライフサイクルについて

2024/09/02に公開

どうも、転職活動中のflutterエンジニアのRy03です。
とある企業の面接でFlutterのStateful Widgetのライフサイクルについて質問され、うまく説明することができませんでした、、、
なので、勉強して覚えたことを書いておくことにしました。
初めての記事ですので、お手柔らかに読んでいただけると幸いです。

Stateful Widgetのライフサイクル

1. createState()

Widget用にMutableなStateオブジェクトを作成する。
StatefulWidgetが初めて作成される際に呼び出される。

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  
  State<MyHomePage> createState() {
    print('createState()');
    return _MyHomePageState();
  }
}

https://api.flutter.dev/flutter/widgets/StatefulWidget/createState.html

2. initState()

Stateオブジェクトがツリーに挿入された直後に一度だけ呼び出す。
ウィジェットが描画される前に一度だけ実行する必要がある設定をここで行う。
(初期データの設定やリスナーの追加など)

  int _counter = 0;
  TextEditingController controller = TextEditingController();

  
  void initState() {
    super.initState();
    print('init state');
    print('is mounted: $mounted'); // true
    _counter = 10;
    controller.addListener(() {
      controller.text.length == 3 ? _incrementCounter() : null;
    });
  }

https://api.flutter.dev/flutter/widgets/State/initState.html

3. didChangeDependencies()

initState()が呼び出された直後に呼ばれる。
その名の通り、ウィジェットが依存しているdependencies(InheritedWidgetなど)に変更があった場合に呼び出される。その後、build()が呼び出されてUIが再描画される。

  
  void didChangeDependencies() {
    super.didChangeDependencies();
  }

https://api.flutter.dev/flutter/widgets/State/didChangeDependencies.html
ステート管理でRiverpodを使ってる方はほぼ使わないでしょう。というか、使えないっぽい↓
https://github.com/rrousselGit/riverpod/discussions/2176

4. build()

現在Stateを元にウィジェットのUIを構築する。
SetState()などでStateの状態が変わるたびに呼び出される。

  
  Widget build(BuildContext context) {
    ...
  }

https://api.flutter.dev/flutter/widgets/State/build.html

5. setState()

ウィジェットのStateを変更し、build()メソッドを再び呼び出してUIを更新する。

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

https://api.flutter.dev/flutter/widgets/State/setState.html

6. didUpdateWidget()

親ウィジェットが変更されたときに呼び出される。
以前のウィジェット(oldWidget)を引数として渡す。
この後Buildメソッドが呼ばれるのでdidUpdateWidget()内でsetStateを呼び出す意味はない。

  
  void didUpdateWidget(covariant MyHomePage oldWidget) {
    super.didUpdateWidget(oldWidget);
    print('didUpdateWidget');
  }

https://api.flutter.dev/flutter/widgets/State/didUpdateWidget.html

7. deactivate()

ウィジェットがツリーから削除されるときに呼び出す。
disposeのように完全に削除するのではなく、後でツリーに再び追加される場合もある。

  
  void deactivate() {
    super.deactivate();
    print('deactivate');
  }

https://api.flutter.dev/flutter/widgets/State/deactivate.html

8. dispose()

ウィジェットがツリーから完全に削除されるときに呼び出す。
リスナーの解除やコントローラーの破棄など行い、リソースを解放させる。

  
  void dispose() {
    super.dispose();
    controller.dispose();
  }

https://api.flutter.dev/flutter/widgets/State/dispose.html

その他:reassemble()

デバッグでHot Reloadなどを行う際に呼び出される。

  
  void reassemble() {
    super.reassemble();
  }

https://api.flutter.dev/flutter/widgets/State/reassemble.html


ざっとですが、FlutterのStateful Widgetのライフサイクルについて学ぶことができました。次の記事では、実際にコードを書いてデモンストレーション用のアプリを用意します。

Discussion