为什么有状态小部件被定义为flutter中的两个类?

Dan*_*T29 18 generics dart flutter

我是新手扑动/飞镖,所以当我尝试制作应用程序时,我也试着理解为什么事情是某种方式.在flutter文档中,有一个有状态小部件的示例代码,如下所示:

class YellowBird extends StatefulWidget {
  const YellowBird({ Key key }) : super(key: key);

  @override
  _YellowBirdState createState() => new _YellowBirdState();
}

class _YellowBirdState extends State<YellowBird> {
  @override
  Widget build(BuildContext context) {
    return new Container(color: const Color(0xFFFFE306));
  }
}
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 为什么他们用两个类而不是一个类定义?我猜测State类可以在其他地方使用,所以最好分开.

  2. 从我的理解,createState()函数返回一个类型的对象State,所以_YellowBirdState extends State有意义,但为什么YellowBird传递到泛型类State?我的猜测它与Yellowbird扩展StatefulWidget课程有关但不太确定.

Rém*_*let 21

原因有很多:

  • 小部件是不可变的.因为StatefulWidget扩展Widget它因此也必须是不可变的.将声明拆分为两个类允许两者StatefulWidget都是不可变的并且 State是可变的.

  • 使用语法实例化窗口小部件new MyWidget().如果我们将两个类合并为一个,new MyWidget()则每次更新父级时都会重置该状态的所有属性.

至于解释 class _MyStatefulState extends State<MyStateful>

这是因为State该类可以Stateful使用该this.widget字段访问它的部分.通用在这里制作类型的字段MyStateful而不是仅仅StatefulWidget.您可能想要访问MyStateful属性.

  • 这种关于不变性的解释对我来说并不适用。这有点像在说,我是一个滴酒不沾的人,但我是在为我的双胞胎喝酒。如果小部件需要状态(线索就在名称中),那么它只是假装是不可变的。另外,我不相信多个小部件需要访问同一状态的用例。当然,这不是需要优化的常见情况。 (10认同)

Ric*_*eap 15

  1. Flutter的主要设计决策之一是重新创建Widgets很便宜,因此build()可以调用在某些内容发生变化时重建小部件树的分支.这对于通过构造函数赋予其不可变值的无状态小部件非常有效.但有状态的小部件需要在构建之间保留它们的状态.在您的示例中,框架可以创建多个YellowBirds,但它只创建一个YellowBirdState.每个新创建的YellowBird都透明地连接到YellowBirdState框架所存在的.

  2. State需要知道其Widget类型的子类,以便编译器知道变量的类型widget.在YellowBirdState你可以参考Widget widget.如果YellowBird有一个成员变量final String foo,编译器就知道这widget.foo是名为foo的String YellowBird.

  • 每个有状态小部件都会创建自己的有状态元素,每个有状态元素通过调用 createState 方法创建一个状态对象。(将其添加到此处以供将来引用它的任何人使用) (2认同)

dan*_*guy 7

Flutter 文档对此进行了解释。

\n
\n

拥有单独的状态和小部件对象可以让其他小部件以完全相同的方式处理无状态和有状态小部件,而不必担心丢失状态。父级不需要保留子级来保留其状态,而是可以随时创建子级的新实例,而不会丢失子级\xe2\x80\x99s 的持久状态。该框架会在适当的时候完成查找和重用现有状态对象的所有工作。

\n
\n

基本上,它是为了使有状态的小部件可以重新实例化(无论何时build(),例如状态发生变化)而不会丢失其状态。

\n

这也是通过 Widget 的不可变性强制执行的,因此可变状态数据必须存储在其他地方:对象State。

\n