In fact when browsing the source code of the Flutter SDK we will see several Stateless Widgets with a constructor const
. That’s because in theory all StatelessWidget
s are immutable and must contain their attributes defined as final
, consequently being able to make use of a constructor const
.
Use a constructor const
means that the whole state of the object can be defined at compile time, so it is necessary that the attributes are final
.
Including by creating a StatelessWidget
with final attributes and ask the IDE(Androidstudio in the example) to create a constructor:
It will automatically create a const constructor:
This is because the IDE’s Dart plugin follows best practices to the fullest defined in the language:
CONSIDER making your constructor const if the class Supports it.
If you have a class Where all the Fields are final, and the constructor does Nothing but initialize them, you can make that constructor const. That Lets users create instances of your class in Places Where constants are required-Inside other Larger constants, switch cases, default Parameter values, etc.
In addition to being a good practice, Flutter benefits greatly from it for his performance.
We know that all Widgets are rendered in a tree, and by updating this state tree (using setState()
), all child widgets are also rendered again, the build()
is re-encumbered. For example, this code:
return Container(
child: Row(
children: <Widget>[
const Text('eu não mudei..')
],
),
);
While executing the setState
the build
of Container
will be executed, after that that of his children, in this case the Row
. However, since the SDK is certain that Text has not been altered, it does not need to be recreated. It is important to note that Flutter is smart enough to identify whether or not a tree Node/Widget has been modified for its rendering, but const assists in this process, in addition to allowing the canonization of this object, imagine this other example:
return Container(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: const Text('canonicalizado'),
)
],
),
);
Note that the use of EdgeInsets
across our Widgets tree is very common for padding assignment. Above, when we use const in the first creation of this object, it was canonized or 'frozen', ie all other places that used the same object (as the Padding
) will point to the same reference of the object in memory, without the need to create multiple instances of the same object.