Reputation: 5772
Is there any objection against using
final foo = Builder(builder: (BuildContext context) {
...
});
instead of
class Foo extends StatelessWidget {
@override
Widget build(Build context) {
...
}
}
?
Upvotes: 1
Views: 600
Reputation: 277057
Using a Builder
instead of making a proper subclass has flaws.
Flutter's widget system uses the runtimeType
variable to determine how it should behave.
To be more specific, when runtimeType
changes, Flutter will unmount the previous widget tree at that location, and then mount the new one.
But by using Builder the runtimeType
never changes, and it confuses the framework.
This, in turn, means that by using Builder
instead of making a StatelessWidget subclass, it could have undesired behaviors like reusing the state of the previous widget tree.
For the sake of an example, consider that we want to switch between two different kinds of widget – both of which instantiate a TextField.
With builders our two widgets would be:
final foo = Builder(builder: (_) => TextField());
final bar = Builder(builder: (_) => TextField());
then used this way:
Widget build(BuildContext context) {
return condition ? foo : bar;
}
With classes we'd have:
class Foo extends StatelessWidget {
@override
Widget build(Build context) => TextField();
}
class Bar extends StatelessWidget {
@override
Widget build(Build context) => TextField();
}
used as such:
Widget build(BuildContext context) {
return condition ? Foo() : Bar();
}
At this point, we run our application and starts typing some things inside the text field from our foo
/Foo
widget.
And then we're doing an action that will switch to bar
/Bar
.
In this step, the result will vary depending on if you used a class or a Builder
:
using foo
/bar
, the text field inside bar
shows the text you typed in the text field from foo
.
using Foo
/Bar
classes, this does not happen. The text field inside Bar
correctly resets to its initial value.
Upvotes: 2