mobileflutterimmutability

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.


Solution

  • From https://api.flutter.dev/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.)