为什么颤振小部件不可变?

Dhr*_*rma 3 mobile immutability flutter

我不明白为什么Flutter对象是不可变的。我在Flutter文档中尝试过,但是并没有帮助。如果有人可以帮助我,我会很感激。

另外,我两天前才开始颤抖,这很棒。

Moh*_*oud 7

不可变性是许多编程语言的基石,使用不可变数据可以更高效 flutter 利用这一优势为每一帧重建不可变视图树

\n\n

一般来说,我们应该将重建交给实际发生变化的子树

\n\n

小部件树是用户界面的不可变描述。我们怎样才能重建其中的一部分而不从根本上重建它呢?好吧,事实上,小部件树并不是一个物化的树结构,具有从父部件到子部件、从根到叶的引用。特别是,StatelessWidget 和 StatefulWidget don\xe2\x80\x99t 具有子引用。它们提供的是构建方法(在有状态的情况下,通过关联的 State 实例)。Flutter 框架在生成或更新实际运行时树结构时递归地调用这些构建方法,该树结构不是 widget 的,而是引用 widget 的 Element 实例的。元素树是可变的,并由 Flutter 框架管理。

\n\n

那么当你在 State 实例上调用 setState 时实际上会发生什么?Flutter框架标记以s对应的元素为根的子树进行重建。当下一帧到期时,该子树将根据 s 的 build 方法返回的小部件树进行更新,而该小部件树又取决于当前的应用程序状态

\n


Gün*_*uer 5

来自https://docs.flutter.io/flutter/widgets/StatefulWidget-class.html

StatefulWidget实例本身是不可变的,并将其可变状态存储在由createState方法创建的单独的State对象中,或存储在该State所订阅的对象中,例如Stream或ChangeNotifier对象,引用存储在StatefulWidget的最终字段中本身。

框架每膨胀一个StatefulWidget就会调用createState,这意味着如果该StatefulWidget已在多个位置插入到树中,则可能会将多个State对象与同一个StatefulWidget关联。同样,如果将StatefulWidget从树中删除并随后再次插入到树中,则框架将再次调用createState来创建新的State对象,从而简化State对象的生命周期。

如果StatefulWidget的创建者使用GlobalKey作为键,则从树中的一个位置移动到另一个位置时,StatefulWidget会保留相同的State对象。因为具有GlobalKey的窗口小部件最多可以在树中的一个位置使用,所以使用GlobalKey的窗口小部件最多具有一个关联的元素。当将具有全局键的小部件从树中的一个位置移动到另一个位置时,该框架通过将与该小部件关联的(唯一)子树从旧位置移植到新位置(而不是在该位置重新创建子树),来利用此属性。新位置)。与StatefulWidget关联的State对象将与子树的其余部分一起移植,这意味着State对象在新位置中被重用(而不是重新创建)。但是,为了有资格进行嫁接,

性能考量

StatefulWidgets有两个主要类别。

第一个是在State.initState中分配资源并将其在State.dispose中处置的资源,但是它不依赖于InheritedWidgets或调用State.setState。此类小部件通常在应用程序或页面的根部使用,并通过ChangeNotifiers,Streams或其他此类对象与子小部件通信。遵循这种模式的有状态的小部件相对便宜(就CPU和GPU周期而言),因为它们一旦构建就永远不会更新。因此,它们可能具有一些复杂且深入的构建方法。

第二类是使用State.setState或依赖于InheritedWidgets的小部件。这些通常在应用程序的生命周期内会多次重建,因此,将重建此类小部件的影响降至最低至关重要。(它们也可以使用State.initState或State.didChangeDependencies并分配资源,但是重要的是它们可以重建。)

“扑对象”是相当广泛的。有不同种类的对象。

状态和窗口小部件被拆分,它们具有不同的生命周期。出于性能原因使用不变性。如果需要更改小部件,请相应地创建一个新实例。检查两个实例是否相同的速度要快于它们的状态是否相同。

这是const经常使用的原因之一。如果构造函数参数相同,则可以确保使用相同的实例。

从上面链接的文档

尽可能使用const小部件。(这等效于缓存小部件并重新使用它。)