Flutter: ライフサイクルメソッドの実行順番

Flutter: ライフサイクルメソッドの実行順番

June 7, 2024

次のメソッドの実行順番を確認するためにログを出力させてみた。

  • createState()
  • build()
  • setState()
  • initState()
  • didChangeDependencies()
  • didUpdateWidget()
  • deactivate()
  • dispose()
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  State<MyApp> createState() {
    print("MyApp.createState()");
    return _MyAppState();
  }
}

class _MyAppState extends State<MyApp> {
  int _count = 0;

  void _increment() {
    setState(() {
      _count++;
    });
    print("MyApp.setState()");
  }

  @override
  void initState() {
    print("_MyAppState.initState()");
    super.initState();
  }

  @override
  void didChangeDependencies() {
    print("_MyAppState.didChangeDependencies()");
    super.didChangeDependencies();
  }

  @override
  void didUpdateWidget(covariant MyApp oldWidget) {
    print("_MyAppState.didUpdateWidget()");
    super.didUpdateWidget(oldWidget);
  }

  @override
  void deactivate() {
    print("_MyAppState.deactivate()");
    super.deactivate();
  }

  @override
  void dispose() {
    print("_MyAppState.dispose()");
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    print("_MyAppState.build()");

    return MaterialApp(
      home: Scaffold(
        body: Column(
          children: [
            if (_count < 3) ...[
              MyCountWidget(count: _count),
              MyButtonWidget(onPress: _increment),
            ] else
              const MyDoneWidget(),
          ],
        ),
      ),
    );
  }
}

class MyCountWidget extends StatefulWidget {
  const MyCountWidget({
    super.key,
    required this.count,
  });

  final int count;

  @override
  State<MyCountWidget> createState() {
    print("MyCountWidget.createState()");
    return _MyCountWidgetState();
  }
}

class _MyCountWidgetState extends State<MyCountWidget> {
  @override
  void initState() {
    print("_MyCountWidgetState.initState()");
    super.initState();
  }

  @override
  void didChangeDependencies() {
    print("_MyCountWidgetState.didChangeDependencies()");
    super.didChangeDependencies();
  }

  @override
  void didUpdateWidget(covariant MyCountWidget oldWidget) {
    print("_MyCountWidgetState.didUpdateWidget()");
    super.didUpdateWidget(oldWidget);
  }

  @override
  void deactivate() {
    print("_MyCountWidgetState.deactivate()");
    super.deactivate();
  }

  @override
  void dispose() {
    print("_MyCountWidgetState.dispose()");
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    print("_MyCountWidgetState.build()");

    return Text("count: ${widget.count}");
  }
}

class MyButtonWidget extends StatefulWidget {
  const MyButtonWidget({
    super.key,
    required this.onPress,
  });

  final VoidCallback onPress;

  @override
  State<MyButtonWidget> createState() {
    print("MyButtonWidget.createState()");
    return _MyButtonWidgetState();
  }
}

class _MyButtonWidgetState extends State<MyButtonWidget> {
  @override
  void initState() {
    print("_MyButtonWidgetState.initState()");
    super.initState();
  }

  @override
  void didChangeDependencies() {
    print("_MyButtonWidgetState.didChangeDependencies()");
    super.didChangeDependencies();
  }

  @override
  void didUpdateWidget(covariant MyButtonWidget oldWidget) {
    print("_MyButtonWidgetState.didUpdateWidget()");
    super.didUpdateWidget(oldWidget);
  }

  @override
  void deactivate() {
    print("_MyButtonWidgetState.deactivate()");
    super.deactivate();
  }

  @override
  void dispose() {
    print("_MyButtonWidgetState.dispose()");
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    print("_MyButtonWidgetState.build()");

    return IconButton(
      icon: const Icon(Icons.add),
      onPressed: widget.onPress,
    );
  }
}

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

  @override
  State<MyDoneWidget> createState() {
    print("MyDoneWidget.createState()");
    return _MyDoneWidgetState();
  }
}

class _MyDoneWidgetState extends State<MyDoneWidget> {
  @override
  void initState() {
    print("_MyDoneWidgetState.initState()");
    super.initState();
  }

  @override
  void didChangeDependencies() {
    print("_MyDoneWidgetState.didChangeDependencies()");
    super.didChangeDependencies();
  }

  @override
  void didUpdateWidget(covariant MyDoneWidget oldWidget) {
    print("_MyDoneWidgetState.didUpdateWidget()");
    super.didUpdateWidget(oldWidget);
  }

  @override
  void deactivate() {
    print("_MyDoneWidgetState.deactivate()");
    super.deactivate();
  }

  @override
  void dispose() {
    print("_MyDoneWidgetState.dispose()");
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    print("_MyDoneWidgetState.build()");

    return const Text("Done");
  }
}

ログ

# 初期
flutter: MyApp.createState()
flutter: _MyAppState.initState()
flutter: _MyAppState.didChangeDependencies()
flutter: _MyAppState.build()
flutter: MyCountWidget.createState()
flutter: _MyCountWidgetState.initState()
flutter: _MyCountWidgetState.didChangeDependencies()
flutter: _MyCountWidgetState.build()
flutter: MyButtonWidget.createState()
flutter: _MyButtonWidgetState.initState()
flutter: _MyButtonWidgetState.didChangeDependencies()
flutter: _MyButtonWidgetState.build()
# カウントアップボタン押下1回目
flutter: MyApp.setState()
flutter: _MyAppState.build()
flutter: _MyCountWidgetState.didUpdateWidget()
flutter: _MyCountWidgetState.build()
flutter: _MyButtonWidgetState.didUpdateWidget()
flutter: _MyButtonWidgetState.build()
# カウントアップボタン押下2回目
flutter: MyApp.setState()
flutter: _MyAppState.build()
flutter: _MyCountWidgetState.didUpdateWidget()
flutter: _MyCountWidgetState.build()
flutter: _MyButtonWidgetState.didUpdateWidget()
flutter: _MyButtonWidgetState.build()
# カウントアップボタン押下3回目(=Done表示に切り替え)
flutter: MyApp.setState()
flutter: _MyAppState.build()
flutter: _MyCountWidgetState.deactivate()
flutter: _MyButtonWidgetState.deactivate()
flutter: MyDoneWidget.createState()
flutter: _MyDoneWidgetState.initState()
flutter: _MyDoneWidgetState.didChangeDependencies()
flutter: _MyDoneWidgetState.build()
flutter: _MyCountWidgetState.dispose()
flutter: _MyButtonWidgetState.dispose()

参考

この Stack Overflow のアンサーが簡潔でわかりやすい。