L'estensione di un widget è davvero un antipattern?

Aug 20 2020

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

3 kuhnroyal Aug 20 2020 at 20:22

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 FormBuildercon 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.

2 jitsm555 Aug 20 2020 at 21:16

Flutter è più di compositionpiuttosto 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 Compositiona mente. Quindi, personalmente non ho mai osservato tali prestazioni o problemi di ritardo con l'ereditarietà, quindi suggerirei che Inheritancenon è una cattiva scelta usarlo.