简体   繁体   English

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

[英]Why are stateful widgets defined as two classes in flutter?

I'm new to flutter/dart, so while I try to make an app I also try to understand why things are a certain way.我是 flutter/dart 的新手,所以当我尝试制作一个应用程序时,我也试图理解为什么事情会以某种方式发生。 In the flutter docs there is example code of a stateful widget as shown:在 flutter docs 中有一个有状态小部件的示例代码,如下所示:

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));
  }
}

Questions:问题:

  1. Why are they defined with two classes as opposed to one?为什么用两个类而不是一个类来定义它们? I'm guessing the State class can be used somewhere else so it was better to be split up.我猜 State 类可以在其他地方使用,所以最好分开。

  2. From what I understand the createState() function returns an object of type State , so having _YellowBirdState extends State makes sense, but why is YellowBird passed into the generic class of State ?根据我的理解, createState()函数返回一个State类型的对象,所以让_YellowBirdState extends State是有道理的,但为什么YellowBird传递到State的泛型类中? My guess it has something to do with Yellowbird extending the StatefulWidget class but not quite sure.我猜这与Yellowbird扩展StatefulWidget类有关,但不太确定。

There are multiple reasons :有多种原因:

  • Widgets are immutable.小部件是不可变的。 Since StatefulWidget extends Widget it therefore must be immutable too.由于StatefulWidget扩展了Widget ,因此它也必须是不可变的。 Splitting the declaration into two classes allows both StatefulWidget to be immutable and State to be mutable.将声明分成两个类允许StatefulWidget是不可变的,而State是可变的。

  • Widgets are instantiated using the syntax new MyWidget() .小部件使用语法new MyWidget()进行实例化。 If we merged both classes into one, new MyWidget() would reset all the properties of the state every time its parent update.如果我们将两个类合并为一个,则new MyWidget()将在每次其父更新时重置状态的所有属性。

As for the explanation of class _MyStatefulState extends State<MyStateful>至于class _MyStatefulState extends State<MyStateful>的解释

That is because the State class can access to it's Stateful part using the this.widget field.那是因为State类可以使用this.widget字段访问它的Stateful部分。 The generic is here to make that field of type MyStateful instead of just StatefulWidget .泛型在这里使该字段为MyStateful类型,而不仅仅是StatefulWidget As you may want to access MyStateful properties.因为您可能想要访问MyStateful属性。

  1. One of the main design decisions of Flutter is that it is cheap to re-create Widgets, so build() can be called to rebuild a branch of the widget tree when something changes. Flutter 的主要设计决策之一是重新创建 Widget 的成本很低,因此可以在发生变化时调用build()来重建 Widget 树的一个分支。 This works fine for stateless widgets which are given their immutable values through the constructor.这适用于通过构造函数赋予其不可变值的无状态小部件。 But stateful widgets need to preserve their state across builds.但是有状态的小部件需要在构建过程中保持它们的状态。 In your example, the framework can create multiple YellowBird s, but it only ever creates one YellowBirdState .在您的示例中,框架可以创建多个YellowBird ,但它只会创建一个YellowBirdState Each newly created YellowBird gets transparently hooked up to the existing YellowBirdState by the framework.每个新创建的YellowBird都通过框架透明地连接到现有的YellowBirdState

  2. A subclass of State needs to know its Widget type so that the compiler knows what type the variable widget is. State的子类需要知道它的 Widget 类型,以便编译器知道变量widget是什么类型。 In YellowBirdState you can refer to the Widget with widget .YellowBirdState您可以使用widget引用 Widget。 If YellowBird had a member variable final String foo , the compiler knows that widget.foo is the String called foo in YellowBird .如果YellowBird有一个成员变量final String foo ,编译器知道widget.foo是名为foo的字符串YellowBird

class YellowBird extends StatefulWidget

StatefulWidget is an immutable class (Immutable class means that once an object is created, we cannot change its values). StatefulWidget 是一个不可变类(不可变类意味着一旦创建了一个对象,我们就不能改变它的值)。

  1. The class must be declared as final (So that child classes can't be created).该类必须声明为 final(这样就不能创建子类)。
  2. Data members in the class must be declared as final.类中的数据成员必须声明为 final。 (So that we can't change the value of it after object creation). (这样我们就不能在对象创建后更改它的值)。
  3. A parameterized constructor.参数化构造函数。
  4. Getter method for all the variables in it.其中所有变量的 Getter 方法。 No setters (To not have the option to change the value of the instance variable).没有设置器(没有更改实例变量值的选项)。

class _YellowBirdState extends State<YellowBird>

State class which type is generic is a mutable class that can be instantiated with different values after creating its object.类型为泛型的状态类是一个可变类,可以在创建其对象后使用不同的值进行实例化。

Same as this StatefulWidget class which is immutable is calling a function of createState() which define the class State of the widget after its called in a flutter so we can change the values of the widget again and again by this approach but we cannot change the type of Stateful or Stateless.与这个不可变的 StatefulWidget 类相同,它正在调用createState()的函数,该函数定义了在颤振中调用后小部件的类State ,因此我们可以通过这种方法一次又一次地更改小部件的值,但我们无法更改有状态或无状态的类型。

The Flutter documentation explains this. Flutter 文档解释了这一点。

Having separate state and widget objects lets other widgets treat both stateless and stateful widgets in exactly the same way, without being concerned about losing state.拥有单独的状态和小部件对象可以让其他小部件以完全相同的方式处理无状态和有状态小部件,而不必担心丢失状态。 Instead of needing to hold on to a child to preserve its state, the parent can create a new instance of the child at any time without losing the child's persistent state.父级可以随时创建子级的新实例,而无需保留子级以保持其状态,而不会丢失子级的持久状态。 The framework does all the work of finding and reusing existing state objects when appropriate.该框架会在适当的时候完成查找和重用现有状态对象的所有工作。

Basically, its so that a Stateful Widget can be re-instantiated (whenever its build() , eg from a state change) without losing its state.基本上,它使有状态小部件可以重新实例化(每当它的build() ,例如从状态更改时)而不会丢失其状态。

This is also enforced by Widgets being immutable, so the mutable state data must be stored elsewhere: the State object.这也是由 Widget 不可变强制执行的,因此可变状态数据必须存储在其他地方: State对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM