Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are flutter widgets immutable?

I am not able to understand why Flutter objects are immutable. I tried it in the Flutter docs but they weren't that helpful. If anyone can help me with this, I'll be thankful.

Also, I just started flutter 2 days ago and it's awesome.

like image 313
Dhruvam Sharma Avatar asked Dec 17 '18 08:12

Dhruvam Sharma


2 Answers

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

StatefulWidget instances themselves are immutable and store their mutable state either in separate State objects that are created by the createState method, or in objects to which that State subscribes, for example Stream or ChangeNotifier objects, to which references are stored in final fields on the StatefulWidget itself.

The framework calls createState whenever it inflates a StatefulWidget, which means that multiple State objects might be associated with the same StatefulWidget if that widget has been inserted into the tree in multiple places. Similarly, if a StatefulWidget is removed from the tree and later inserted in to the tree again, the framework will call createState again to create a fresh State object, simplifying the lifecycle of State objects.

A StatefulWidget keeps the same State object when moving from one location in the tree to another if its creator used a GlobalKey for its key. Because a widget with a GlobalKey can be used in at most one location in the tree, a widget that uses a GlobalKey has at most one associated element. The framework takes advantage of this property when moving a widget with a global key from one location in the tree to another by grafting the (unique) subtree associated with that widget from the old location to the new location (instead of recreating the subtree at the new location). The State objects associated with StatefulWidget are grafted along with the rest of the subtree, which means the State object is reused (instead of being recreated) in the new location. However, in order to be eligible for grafting, the widget must be inserted into the new location in the same animation frame in which it was removed from the old location.

Performance considerations

There are two primary categories of StatefulWidgets.

The first is one which allocates resources in State.initState and disposes of them in State.dispose, but which does not depend on InheritedWidgets or call State.setState. Such widgets are commonly used at the root of an application or page, and communicate with subwidgets via ChangeNotifiers, Streams, or other such objects. Stateful widgets following such a pattern are relatively cheap (in terms of CPU and GPU cycles), because they are built once then never update. They can, therefore, have somewhat complicated and deep build methods.

The second category is widgets that use State.setState or depend on InheritedWidgets. These will typically rebuild many times during the application's lifetime, and it is therefore important to minimize the impact of rebuilding such a widget. (They may also use State.initState or State.didChangeDependencies and allocate resources, but the important part is that they rebuild.)

"Flutter objects" is quite broad. There are different kinds of objects.

State and widget are split and they have different lifecycles. Immutability is used for performance reasons. If the widget needs to change, create a new instance set up accordingly. It's quicker to check if two instances are identical than if their state is the same.

This is one of the reasons const is used often. It ensures that identical instances are used if the constructor parameters are the same.

From the docs linked to above

Use const widgets where possible. (This is equivalent to caching a widget and re-using it.)

like image 160
Günter Zöchbauer Avatar answered Oct 22 '22 15:10

Günter Zöchbauer


Immutability is the cornerstone of many programming languages and using immutable data can be more efficient flutter Take this advantage to rebuild the immutable view tree for every frame

In general, we should confide rebuilding to the subtrees that actually change

The widget tree is an immutable description of the user interface. How can we rebuild part of that without reconstructing it from the root? Well, in truth, the widget tree is not a materialized tree structure with references from parent widget to child widget, root to leaf. In particular, StatelessWidget and StatefulWidget don’t have child references. What they do provide are build methods (in the stateful case, via the associated State instances). The Flutter framework calls those build methods, recursively, while generating or updating an actual runtime tree structure, not of widgets, but of Element instances referring to widgets. The element tree is mutable, and managed by the Flutter framework.

So what actually happens when you call setState on a State instance s? The Flutter framework marks the subtree rooted at the element corresponding to s for a rebuild. When the next frame is due, that subtree is updated based on the widget tree returned by the build method of s, which in turn depends on current app state

like image 44
Mohammed Mahmoud Avatar answered Oct 22 '22 16:10

Mohammed Mahmoud