扩展小部件真的是一种反模式吗?

问题描述

我在couple places中读到,扩展Flutter小部件是一种反模式。是真的吗?

我已经使用小部件子类化通过将要删除的小部件子类化并将其小部件放入其构造函数中来减少嵌套,就像这样

class Foo extends FormBuilder {
    Foo() : super (
        // bunch of widgets here
    );
}

扩展无状态小部件似乎更受欢迎,但它向树中添加了几行代码一个小部件,这不是我的偏爱:

class Foo extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return FormBuilder(
       // bunch of widgets here
    );
}

我读过从函数返回小部件是一种反模式,因为它breaks rendering optimization。我的第一种方法是否同样具有隐藏的副作用?也就是说,它真的是反模式吗?

解决方法

扩展状态小部件可能会导致问题,因为它们的状态被键入超类,并且您不能扩展它们的状态,因为大多数状态类都是私有的。许多查找方法,例如BuildContext.findAncestorStateOfType()可能会失败。

扩展无状态小部件在大多数情况下应该可以使用,但您已经发现,不建议这样做。

通常,由于Flutter具有整个反应式和窗口小部件的性质,composition over inheritance的主体是一个很好的遵循模式。

您将小部件组合为新的小部件,新的小部件,新的小部件,新的小部件...您明白了。

除此之外,您还保存了两行代码,这些代码大多数都是自动生成的,但是您却抢走了VSCode / IntelliJ中的所有简单帮助程序,例如“用填充包装小部件”。要在应用程序中的所有用法上加上填充来填充扩展FormBuilder,要困难得多。如果编写起来很简单,只需将其包装在Foo中即可。用于主题,颜色,字体样式等的所有其他小部件也是如此。填充只是一个示例。

,

颤振更多地是composition而不是Inheritance。但是,当需要在子级中重用父级小部件时,使用StatelessWidget进行继承将总是有用的。

例如:

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();
  }
}

因此,将调用 Foo()的小部件,即小部件元素树将是

-Foo

-容器

如果其正常成分为元素树 为此

class Foo extends StatelessWidget {
      Foo() : super();
    
      @override
      Widget build(BuildContext context) {
        return FormBuilder();
      }
    }

-Foo

-FormBuilder

-文字

没有任何官方文档指出其不良模式,而是通过牢记Composition来设计抖动。因此,就我个人而言,我从未观察到任何此类性能或继承方面的滞后问题,因此我建议使用Inheritance并不是一个不错的选择。