The Widget constructor takes a key as a named
parameter. However, such a parameter is optional:
class Widget {
Widget({ Key? key }) { ...}
}
This means that widgets inheriting from it can be created without a key parameter.
class MyWidget extends Widget {
MyWidget() : super(); // No key parameter forwarded
}
The same applies to the StatefulWidget and the StatelessWidget.
They both define constructors with an optional key parameter, which:
- is forwarded to the
Widget constructor when specified
- is not forwarded when omitted
That results in a widget with a null key.
While this is not a problem in itself, it is a good practice to always provide a key parameter to widgets, as it can be useful for
debugging, testing, and performance optimizations.
For example, when a widget needs to potentially be rebuilt, Flutter compares the new widget with the old one to determine what has changed. If the
widgets have the same key, Flutter assumes that they are the same, and it will not perform the rebuild. This can be useful when building the widget is
expensive, or when the it has a state that should be preserved across rebuilds.
Scenarios where keys are useful include preserving the scroll position of a list, the state of a form, or the content of an editing collection.