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

#ライフサイクルとは
ライフサイクルとは、人間でいうと誕生してから死ぬまでのこと
この記事の文脈では、``画面が誕生してから消滅するまでのこと``です！
#StatelessWidgetのライフサイクル
```Dart
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もまた同じツリー構造になります！！

```Dart
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()の引数に自分自身を代入しています。

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

```Dart
  @override
  StatelessElement createElement() => StatelessElement(this);
```
以下のような状態になっています。
StatelessElementクラスがMyAppクラスを参照しています。
![スクリーンショット 2021-07-02 14.16.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/839966/dbb57b13-4ead-66b9-b2f3-c5a42f06bedb.png)
ここで、MyAppの下のMaterialAppはStatefulWidgetを継承しているのでStatefulElementが作成されます。そして、StatefulElementはMaterialAppを参照します。この作業がTextまで繰り返されて、WidgetとElementのツリー構造が形成されます。そして、ElementとWidgetは一対一の関係で参照しています。

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

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

```Dart
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オブジェクトを保持しています。

```Dart
  /// 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()を実行しています。