9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

なぜStatefullWidgetではなくStateがbuildメソッドを持っているのか

Posted at

転載: https://www.yslibrary.net/2018/07/22/flutter-statefullwidget-build/

最近趣味と実益を兼ねてFlutterを触っている。

だいたいReactっぽくて良さそうな感じ。React Nativeと違って、UIレイヤについては基本的にFlutterの中で完結するのが好み。

ただStatefulWidgetを作るときにちょっと気になることがあった。StatefulWidgetはそれ以外にWidgetの状態を管理するStateクラスが必要なんだけど、StatefulWidgetではなくStateの方にUIを描画するbuildメソッドがあるのだ。

ReactでもそうだしMVPやらMVVMでもそうだけど、だいたい状態を管理するクラスとUIを描画するクラスを分離することで責任を分離している。それをなぜわざわざStateクラスにbuildメソッドが生えているんだろう? と違和感しかなかった。

そんなわけでちょっと調べてみたら、やっぱり同じように思う人はいたらしくissueがたっていた。

FAQ request: why is the build() method on State, and not StatefulWidget ?

要約すると下記のような理由らしい。

StatefulWidgetbuildメソッドを生やすことにすると、メソッドシグネチャがStatefulWidget#build(BuildContext, State)になる。
このメソッドの中でクロージャを定義すると暗黙的にthis(この場合はStatefulWidget)がキャプチャされる。で、buildメソッドが呼ばれたときに、StatefulWidgetは作り直されたにも関わらずクロージャのthisは古いStatefulWidgetを参照したままで古い状態を参照してしまう。
一方State#build(BuildContext)であれば、StateStatefulWidgetが再生成されたときでもそのまま保持されるので、thisの対象が変わることはない、ということだ。

あとは、StatefulWidget#build(BuildContext, State)だと、これ継承した新しいStatefulWidgetを作ったときに実装の詳細であるStateを子クラスに公開しなければならなくなる、とか。

仕様的にこうせざるを得なかった、というのはわかったけどやっぱり釈然としない感じはある。

こういった点を何とかするためにBLoCパターンとかMVW系のデザインパターンを実装するんだろうけど、そのへんはまだ分かりきっていないので引き続き調べる。

ちなみに上述のissueの中身は現在APIドキュメントの方にも記載されている。

9
3
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
9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?