LoginSignup
7
9

More than 1 year has passed since last update.

Flutterライフサイクルについて理解する

Last updated at Posted at 2021-08-06

ライフサイクルとは

ライフサイクルとは、人間でいうと誕生してから死ぬまでのこと
この記事の文脈では、画面が誕生してから消滅するまでのことです!

StatelessWidgetのライフサイクル

abstract class StatelessWidget extends Widget {
  /// Initializes [key] for subclasses.
  const StatelessWidget({ Key? key }) : super(key: key);

  /// Creates a [StatelessElement] to manage this widget's location in the tree.
  ///
  /// It is uncommon for subclasses to override this method.
  @override
  StatelessElement createElement() => StatelessElement(this);

  @protected
  Widget build(BuildContext context);
}

StatelessWidgetの中身を具体的に見ていきます。
最も重要な部分:createElementメソッド
このメソッドでStatelessElementをインスタンス化しています。
StatelessWidgetに限らずウィジェットクラスはcreateElementでエレメントを必ずインスタンス化します。
FlutterはWidgetをツリー構造で作成していくので、ツリー構造という概念をご存知だと思います。
Elementもまた同じツリー構造になります!!

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Text("テキスト"),
        ),
      ),
    );
  }
}

具体的に見ていきましょう!
(MyAppは抽象クラスのStatelessWidgetを継承しているので、buildメソッドを必ず実行しなければなりません。)
上のMyAppクラスがインスタンス化されると、StatelessElementクラスもインスタンス化されます。
その時、StatelessElement()の引数に自分自身を代入しています。

これはどういうこのなのでしょうか?

  @override
  StatelessElement createElement() => StatelessElement(this);

以下のような状態になっています。
StatelessElementクラスがMyAppクラスを参照しています。
スクリーンショット 2021-07-02 14.16.32.png
ここで、MyAppの下のMaterialAppはStatefulWidgetを継承しているのでStatefulElementが作成されます。そして、StatefulElementはMaterialAppを参照します。この作業がTextまで繰り返されて、WidgetとElementのツリー構造が形成されます。そして、ElementとWidgetは一対一の関係で参照しています。

StatelessWidgetは、構築されたときに1回しか描画されないウィジットです。ユーザーアクションに基づいて再描画されることはありません。
てことで、StatelessWidgetのライフサイクルは2つです。
StatelessElementを作成してエレメントツリーに追加する前のinitial状態と、追加した後のactiveの状態になります。

StatefulWidgetのライフサイクル

StatefulWidgetクラスの場合は、ちょっぴり複雑です。
まずは、StatefulWidgetクラスのソースコードをみよう。

abstract class StatefulWidget extends Widget {
  /// Initializes [key] for subclasses.
  const StatefulWidget({ Key? key }) : super(key: key);

  /// Creates a [StatefulElement] to manage this widget's location in the tree.
  ///
  /// It is uncommon for subclasses to override this method.
  @override
  StatefulElement createElement() => StatefulElement(this);

  @protected
  @factory
  State createState();
}

StatelessWidgetと同様にWidgetクラスを継承しており、createElement()メソッドがあります。
StatefulElementのソースコードの中には、Stateオブジェクトを保持しています。

  /// The [State] instance associated with this location in the tree.
  ///
  /// There is a one-to-one relationship between [State] objects and the
  /// [StatefulElement] objects that hold them. The [State] objects are created
  /// by [StatefulElement] in [mount].
  final State<StatefulWidget> state;

つまり、StatefulWidgetはStatelessWidgetと同様に変更可能な状態を保持しておらず、State<StatefulWidget>を保持して、状態を管理しています。

setState()メソッド

StatefulWidgetクラスの醍醐味はStateクラス内の値を変化さえることで再描画することです。再描画したいときに呼び出すのがsetState()です。これが呼ばれることで、build()メソッドが再実行されます。もう少し勉強していくと、アプリを全てStatelessWidgetクラスで作ることも可能です。その時も同様にStatelessWidgetクラス内のWidgetがStatefulWidgetを継承していて、内部でsetState()を実行しています。

7
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
9