🤔

Flutter Statelessウィジェットってなんだ

2021/09/07に公開

Statelessウィジェットってそもそも何なのか プログラミングノート

Statelessウィジェットについて調べてみた

私がFlutterの公式ドキュメントを読む中で疑問に思った用語や基本的な構造の理解についてまとめていくプログラミングノート

今回のテーマはStatelessウィジェット。

Flutter公式ドキュメント「write your first app」では初学者が最初に書くコードの解説が記述されている。

その中のvoid main()については前回のプログラミングノートで、ひとまず理解したところだ(実践的な内容は改めて学ぶつもりだ)。

今回はstatelessウィジェットについて理解を深めていきたい。正直なところ、すでにこの辺りのチュートリアルは一通り、真似してコードを書いているものの、statelessウィジェットとstatefulウィジェットの違いや、それぞれの性質を自分の言葉で説明できるかと問われればかなり怪しい。今回は、自分の言葉でStatelessウィジェットを説明できるようになるためのプログラミングノートだ。

Stateless widgetとは

まず、結論として各種ドキュメントや自身でコードを書いてみて分かったことは、statelessウィジェットで扱う値は変化しないということである。

StatelessWidgetで扱うあたいはすべて不変的でありプロパティを変更することはできません。
すべての値はfinalな値となります。 StatefulWidgetではウィジェットの生存期間中に変更される値を維持することができ、実装するには、少なくとも2つのクラスが必要です。

Stateクラスのインスタンスを作成するStatefulWidgetクラス
Stateクラス
StatefulWidgetクラスそれ自体は不変ですが、Stateクラスでウィジェットの存続期間中は値を保持>します。

Flutter Doc JP Statefulウィジェット https://flutter.ctrnost.com/tutorial/tutorial05/ 2021/09/06に引用

しかし、そもそもStateとは何か。Stateとは日本語で「状態」を意味する。RPGなどでキャラクターの能力が確認できる「ステータス」も同じ語源であるようです。

ということは、statelessというのは状態がない、状態を持たないウィジェットということになりそうです。初学者の間は「Statelessウィジェット = 静的」であると覚えておいて間違いではなさそうです(しかし、後々それでは説明できないものも出てくるようです)。

また、Statelessウィジェットはその中で記述された関数(ウィジェットの描画をしている関数)を上書きし、戻り値をもらうことで画面に描画しているようです。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Welcome to Flutter'),
        ),
        body: const Center(
          child: Text('Hello World'),
        ),
      ),
    );
  }
}

StatelessWidgetは、build関数をoverride(上書き)し、build関数内で描画するWidgetを返すことで描画を行なっています。

もし子WidgetであるStatelessWidgetで使用した変数を親Widgetにて変更した場合、子であるStatelessWidgetは全て再描画(build)されます。

TECHRISE 【Flutter入門】StatelessWidgetとStatefulWidgetの違い https://tech-rise.net/difference-between-stateless-widget-and-stateful-widget/#:~:text=StatelessWidgetとは、State(状態,であると言えます。 2021/09/06に引用

この辺りの、Stalessウィジェット内の関数を上書きするという説明については「@override」について理解する必要があると考えます。

とにかく、Statelessウィジェットで呼び出される関数は描画したいものを戻り値として返す必要があるようですね。よく見られるのは、build関数内の、MaterialAppだったり、Scaffoldです。これらは最初にreturnしておかないと、エラーを起こすと考えられます。

初学者の仮説

そして、気がついた。

あ、Stateful widgetってこいつ自身もクラスじゃん(当たり前なのかも知れないけど)。

だから、MyAppにStatelessを継承(extends)させて、その性質をbuild()に上書きしているってことか。

Statelessを引き継いだクラスはStatelessの記述ルールで書かないとエラー吐くっぽい。ということはStatefulも親クラスとして使うんだから、同様のルールや使うべきものが用意されているってことかな。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Welcome to Flutter'),
        ),
        body: const Center(
          child: Text('Hello World'),
        ),
      ),
    );
  }
}

初学者が理解を深めるためのプログラミングノート

・extendsについて理解する

・void main()とは

Discussion