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

この記事からわかること
- Flutter/DartのStatefulWidgetのライフサイクルとは
- 種類や違いまとめ
- createState/initState/didChangeDependencies/build/deactivate/dispose
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Koala
- Xcode:16.0
- Flutter:3.29.2
- Dart:3.7.2
- Mac M1:Sequoia 15.4
StatefulWidgetのライフサイクル
FlutterでUIを頻繁に更新する際に使用されるStatefulWidget
はライフサイクルによって状態の変化や描画のタイミングなどを管理されてます。StatefulWidget
は状態を持つことができるWidgetで内部で管理されるState
オブジェクトと一対となり状態が管理されています。
StatefulWidget
/State
のライフサイクルは以下のようになっています。
- createState・・・Widget作成時
- initState・・・State生成後1度だけ
- didChangeDependencies・・・初回+InheritedWidgetが変化した時
- build・・・UIの描画タイミング
- deactivate・・・Widgetがツリーから外れる直前
- dispose・・・完全に破棄される直前
createState
createState
はWidget作成時に呼び出されるメソッドです。ここではStatefulWidget
で管理されるStateオブジェクトを作成して返却します。任意の処理を挟むことも可能ではありますが、初期化時に呼び出したい処理は後続のinitState
側で呼び出す方が安全です。
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
@override
State<MyStatefulWidget> createState() {
print('✅ createState');
return _MyStatefulWidgetState();
}
}
initState
initState
はState生成後1度だけ呼び出されるメソッドです。Widgetがツリーに追加された直後に呼ばれるため初期化時に挟みたいAPIやDB処理などの非同期処理などはここで挟むことが推奨されています。
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
@override
void initState() {
super.initState();
print('✅ initState');
}
}
didChangeDependencies
didChangeDependencies
はStateオブジェクトの依存関係が変更されたときに呼び出されるメソッドです。ここでいう依存関係とはInheritedWidget
のことで例えばLocale
やTheme
、MediaQuery
、Provider
などが更新、変更された場合に呼ばれます。
@override
void didChangeDependencies() {
super.didChangeDependencies();
print('✅ didChangeDependencies');
}
build
build
は画面にViewを描画する際に呼び出されるメソッドです。初回の画面描画や状態が更新される(setStateが呼び出される)と都度呼び出されます。ここで返却するWidget
がこのStatefulWidgetで管理、表示されるUIになります。
@override
Widget build(BuildContext context) {
print('✅ build');
return Text("UI");
}
deactivate
deactivate
はWidgetがツリーから外れる直前に呼び出されるメソッドです。この段階では再度Widgetが追加される可能性があるためツリーから外されるだけで完全に破棄されるわけではありません。
@override
void deactivate() {
print('⚠️ deactivate');
super.deactivate();
}
dispose
dispose
はWidgetが完全に破棄される直前に呼び出されるメソッドです。Widget自体が完全に不要になるタイミングのためリソースの解放やアニメーションの停止など後始末処理はここで呼び出します。
@override
void dispose() {
print('🗑️ dispose');
super.dispose();
}
サンプルコード
ライフサイクルの順番を確認するためのサンプルコードを記載しておきます。出力順番は以下のようになります。
flutter: ✅ initState
flutter: ✅ didChangeDependencies
flutter: ✅ build
flutter: ⚠️ deactivate
flutter: 🗑️ dispose
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
@override
void initState() {
super.initState();
print('✅ initState');
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
print('✅ didChangeDependencies');
}
@override
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('再描画!'),
),
],
),
),
);
}
@override
void deactivate() {
print('⚠️ deactivate');
super.deactivate();
}
@override
void dispose() {
print('🗑️ dispose');
super.dispose();
}
}
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。