本稿、あるいは本シリーズは初学者が公式ドキュメントを参考に理解を深めるプログラミングノートである。
先日、Flutterのデモコードを参考にKeyクラスの使い所を理解するために、ウィジェットツリー(ツリー構造)について学んだ。そこでは、開発者がWidgetでUIを作り上げていく時に、Elementツリーなるものができており、それこそがWidget同士を参照し、処理や描画を担っているものであるということが分かりました。つまり、ツリー構造は開発者側のイメージであり、実際の構造はElement要素によって成り立っている。
しかし、せっかくなら、もっとElementについて学んでみたい。もし、あなたがすでにFlutterでいくつかアプリを開発している場合、こちらの参考文献の方がより詳しく知ることができる。
本稿は参考文献をもとに、初学者である私自身がなるべく分かりやすくなるよう、噛み砕いて学んでみる。
FlutterにおけるElementとは Widgetという設計図をもとに形成される描画とコンポーネントのためのインスタンス、と表現してみた……(正直、自信はないが開発者が宣言的に配置するWidgetはElementにとっての設計図であるという部分を重視したい)。
というのも、Elementと一口に言っても、ComponentElementとRenderObjectElementの二つがあり、実際の画面に描画関わるのは後者である。
ComponentElementは公式ドキュメント曰く、他のElementを形成するElementだという。また、参考文献ではこのように述べられている。
まず、Elementには大別して2種類あります。
ComponentElement
RenderObjectElement普通にFlutterアプリを書いてて通常継承して利用する以下の3つは、createElementが呼ばれた時に前者のComponentElementを返します。それ自体は描画には直接関係せず、描画は子Widget以下のRenderObjectElementに委ねます。
・StatelessWidget
・StatefullWidget
・InheritedWidgetRenderObjectツリー構築に関係するのは後者のRenderObjectElementです。createElementが呼ばれた時にRenderObjectElementを返すWidgetはRenderObjectWidgetという抽象クラスを継承しています。
mono Flutter の Widget ツリーの裏側で起こっていること https://medium.com/flutter-jp/dive-into-flutter-4add38741d07 2021/09/13に引用
全てを理解できているわけではないが、その名前の通りコンポーネントを形作るElementをComponentElement、Widgetの描画に関するものをRenderObjectElementが担っているという印象だ。
私は以前にVue.jsを触っていたが、コンポーネント単位でファイルを管理でき、再利用が非常に容易だったことを思い出した。FlutterではそれらをWidget同士をつなげて作っていくが、それらは宣言しない限りステートレスである。そして、必要に応じて、Statefulだよと宣言することで、状態を持ってくれる。そうした切り替えというか、内部的な動きをしてくれるのが、ComponentElementというものと認識している。
本稿や先日の記事の目的はFlutterのデモコードである、カウントアプリに登場する Key? key という記述の理解である。Flutterが根本的な仕組みを少しだけ理解することができたため、次回はKeyについて学んでみたい。