The first case you are creating your own Widget by extending and using composition of other Widgets. This created Widget has methods and attributes that make it possible for Flutter to keep better control of the widgets hierarchy. It can notice when some Widget has changed and needs to be redesigned, without affecting and re-drawing other Widgets that don’t need.
What you showed in the second case is not a creation of a "Pure Widget". You are creating a method that this in turn returns a widget. When you do this, and want to display this widget, you will need to call this method inside the Build
where you want to display. (In a container, for example).
This generates some negative points:
This function will be called whenever the top widget is redesigned, even when it is not needed and the internal widget has not changed.
Your Widgets tree won’t exactly depict the relationship between Widgets. This relation is useful for state management, for UI management, for debugging in general. You know the variable context
that the build method accepts as a parameter? It will not have its value portraying the position correctly. These are some examples of problems that this second negative point can bring.
The code gets more verbose and confusing. You’ll need to call this method wherever you want to use this widget. If you need to do a procedure or calculation several times within this widget, you will not be able to extract a function for such.
You will not be able to use the tools you already have ready to be a Widget itself. You lose control over his life cycle. (Will not be able to be notified when it is started, was displayed/navigated, etc. At least not without a very large gambiarra.)
So answering:
Is there any disadvantage between these two forms?
Yes, as shown above, the correct and most advantageous way is the first.
Taking into account the first scenario, performance loss may occur due to multiple nested build widgets?
No, there is a difference in the number of functions called. Its function meuWidget
will be putting yourself in charge of a build
. Also, remember that Flutter is in charge of calling Build only when necessary.(Here, in the first paragraph, in English.).
In which situation one is more recommended than the other?
I recommend never using the second form. At least not in some larger or more serious application. Thinking more broadly, maybe you can use to facilitate a repetition, for example:
Widget criarColuna(){
List<Container> filhos=[];
for (int i=0; i<10; i++){
filhos.add(Container());
}
return Column(children: filhos,);
}
But even in this case, there are ways more elegant to be made (after Dart 2.3):
children: <Widget>[for (int i=0; i<10; i++) Container(),],
For a more detailed reading, suggest this answer. (in English)
To complement the answer, there are these two links that may be useful as well (Both in English): Splitting widgets to methods is a performance antipattern | And | What is the Difference between functions and classes to create reusable widgets?
– Matheus Ribeiro
Our cool, I didn’t know this scheme of making one
FOR-LOOP
within the array widgets– Matheus Ribeiro