L'estensione di un widget è davvero un antipattern?
Ho letto in un paio di punti che l'estensione di un widget Flutter è un anti-pattern. È vero?
Ho usato la sottoclasse dei widget per ridurre la nidificazione creando sottoclassi il widget che sto rimuovendo e inserendo i suoi widget nel suo costruttore, in questo modo
class Foo extends FormBuilder {
Foo() : super (
// bunch of widgets here
);
}
L'estensione di un widget senza stato sembra più popolare, ma aggiunge qualche altra riga di codice e un widget all'albero, che non è la mia preferenza:
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FormBuilder(
// bunch of widgets here
);
}
Ho letto che restituire un widget da una funzione è un antipattern perché interrompe l'ottimizzazione del rendering . Anche il mio primo approccio ha effetti collaterali nascosti? Cioè, è davvero un antipattern?
Risposte
L'estensione dei widget con stato può portare a problemi poiché il loro stato viene digitato nella superclasse e non è possibile estenderne lo stato poiché la maggior parte delle classi di stato sono mantenute private. Molti metodi di ricerca come BuildContext.findAncestorStateOfType()
potrebbero fallire.
L'estensione di widget senza stato dovrebbe funzionare nella maggior parte dei casi ma non è consigliata, come hai già scoperto.
In generale, con l'intera natura reattiva e widget di Flutter, il principio della composizione rispetto all'ereditarietà è un buon modello da seguire.
Componi i widget in nuovi widget in nuovi widget in nuovi widget in nuovi widget ... Hai capito.
Oltre a ciò, salvi 2 righe di codice che per lo più vengono generate automaticamente ma ti derubano di tutti i semplici helper in VSCode / IntelliJ come "Wrap widget with padding". È molto più difficile avvolgere l'estensione FormBuilder
con un'imbottitura su tutti gli usi nella tua app. Se lo componi è semplice, avvolgilo dentro Foo
. Lo stesso vale per tutti gli altri widget che usi per temi, colori, stili di carattere ecc. - Il riempimento è solo un esempio.
Flutter è più di composition
piuttosto che Inheritance
. Ma l'ereditarietà usando StatelessWidget sarà sempre utile quando i widget padre devono essere riutilizzati nel figlio.
Per esempio:
class FormBuilder extends StatelessWidget {
Widget getWidget() {
return Text('Child Text');
}
@override
Widget build(BuildContext context) {
return Text('FormBuilder Text');
}
}
class Foo extends FormBuilder {
Foo() : super();
@override
Widget build(BuildContext context) {
return getWidget();
}
}
Quindi, il widget che chiamerà Foo () Widget sarà l'albero degli elementi widget
- Foo
- Contenitore
Se la sua composizione normale, l' albero degli elementi sarebbe per questo
class Foo extends StatelessWidget {
Foo() : super();
@override
Widget build(BuildContext context) {
return FormBuilder();
}
}
- Foo
- FormBuilder
-- Testo
Non c'è alcun documento ufficiale che dica il suo cattivo schema ma svolazzare progettato tenendo Composition
a mente. Quindi, personalmente non ho mai osservato tali prestazioni o problemi di ritardo con l'ereditarietà, quindi suggerirei che Inheritance
non è una cattiva scelta usarlo.