【Flutter/Dart】StatefulWidgetのライフサイクルの種類と違い

【Flutter/Dart】StatefulWidgetのライフサイクルの種類と違い

この記事からわかること

  • Flutter/DartStatefulWidgetライフサイクルとは
  • 種類違いまとめ
  • createState/initState/didChangeDependencies/build/deactivate/dispose

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

StatefulWidgetのライフサイクル

公式リファレンス:State-class

FlutterでUIを頻繁に更新する際に使用されるStatefulWidgetはライフサイクルによって状態の変化や描画のタイミングなどを管理されてます。StatefulWidgetは状態を持つことができるWidgetで内部で管理されるStateオブジェクトと一対となり状態が管理されています。

StatefulWidget/Stateのライフサイクルは以下のようになっています。

  1. createState・・・Widget作成時
  2. initState・・・State生成後1度だけ
  3. didChangeDependencies・・・初回+InheritedWidgetが変化した時
  4. build・・・UIの描画タイミング
  5. deactivate・・・Widgetがツリーから外れる直前
  6. dispose・・・完全に破棄される直前

createState

createStateWidget作成時に呼び出されるメソッドです。ここではStatefulWidgetで管理されるStateオブジェクトを作成して返却します。任意の処理を挟むことも可能ではありますが、初期化時に呼び出したい処理は後続のinitState側で呼び出す方が安全です。

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({super.key});

  
  State<MyStatefulWidget> createState() {
    print('✅ createState');
    return _MyStatefulWidgetState();
  }
}

initState

initStateState生成後1度だけ呼び出されるメソッドです。Widgetがツリーに追加された直後に呼ばれるため初期化時に挟みたいAPIやDB処理などの非同期処理などはここで挟むことが推奨されています。

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  
  void initState() {
    super.initState();
    print('✅ initState');
  }
}

didChangeDependencies

didChangeDependenciesStateオブジェクトの依存関係が変更されたときに呼び出されるメソッドです。ここでいう依存関係とはInheritedWidgetのことで例えばLocaleThemeMediaQueryProviderなどが更新、変更された場合に呼ばれます。


void didChangeDependencies() {
  super.didChangeDependencies();
  print('✅ didChangeDependencies');
}

build

build画面にViewを描画する際に呼び出されるメソッドです。初回の画面描画や状態が更新される(setStateが呼び出される)と都度呼び出されます。ここで返却するWidgetがこのStatefulWidgetで管理、表示されるUIになります。


Widget build(BuildContext context) {
  print('✅ build');
  return Text("UI");
}

deactivate

deactivateWidgetがツリーから外れる直前に呼び出されるメソッドです。この段階では再度Widgetが追加される可能性があるためツリーから外されるだけで完全に破棄されるわけではありません


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

dispose

disposeWidgetが完全に破棄される直前に呼び出されるメソッドです。Widget自体が完全に不要になるタイミングのためリソースの解放やアニメーションの停止など後始末処理はここで呼び出します。


void dispose() {
  print('🗑️ dispose');
  super.dispose();
}

サンプルコード

ライフサイクルの順番を確認するためのサンプルコードを記載しておきます。出力順番は以下のようになります。

flutter: ✅ initState
flutter: ✅ didChangeDependencies
flutter: ✅ build
flutter: ⚠️ deactivate
flutter: 🗑️ dispose
class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({super.key});

  
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  
  void initState() {
    super.initState();
    print('✅ initState');
  }

  
  void didChangeDependencies() {
    super.didChangeDependencies();
    print('✅ didChangeDependencies');
  }

  
  Widget build(BuildContext context) {
    print('✅ build');
    return Card(
      color: Colors.blue.shade100,
      margin: const EdgeInsets.all(16),
      child: Padding(
        padding: const EdgeInsets.all(24.0),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Text('StatefulWidget 表示中'),
            const SizedBox(height: 8),
            ElevatedButton(
              onPressed: () => setState(() {}),
              child: const Text('再描画!'),
            ),
          ],
        ),
      ),
    );
  }

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

  
  void dispose() {
    print('🗑️ dispose');
    super.dispose();
  }
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article