一尘不染

创建可重用窗口小部件的函数和类之间有什么区别?

flutter

我已经意识到,可以使用普通函数创建小部件,而不用继承StatelessWidget的子类。一个例子是这样的:

Widget function({ String title, VoidCallback callback }) {
  return GestureDetector(
    onTap: callback,
    child: // some widget
  );
}

这很有趣,因为它需要 远远 比一个全面的类更少的代码。例:

class SomeWidget extends StatelessWidget {
  final VoidCallback callback;
  final String title;

  const SomeWidget({Key key, this.callback, this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
      return GestureDetector(
        onTap: callback,
        child: // some widget
      );
  }
}

所以我一直在想:创建小部件的函数和类之间在语法上是否有区别?使用函数是否是一种好习惯?


阅读 217

收藏
2020-08-13

共1个答案

一尘不染

TL; DR:相对于函数,更喜欢使用类来制作 可重用的 小部件树。


编辑 :弥补一些误解:这不是引起问题的函数,而是解决一些问题的类。

如果一个函数可以做同样的事情,Flutter将不会有StatelessWidget

同样,它主要针对可重用的公共小部件。私有功能只使用一次并不重要,尽管知道这种行为仍然很好。


使用函数而不是使用类之间有一个重要的区别,即:框架不知道函数,但是可以看到类。

考虑以下“窗口小部件”功能:

Widget functionWidget({ Widget child}) {
  return Container(child: child);
}

使用这种方式:

functionWidget(
  child: functionWidget(),
);

它相当于类:

class ClassWidget extends StatelessWidget {
  final Widget child;

  const ClassWidget({Key key, this.child}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: child,
    );
  }
}

这样使用:

new ClassWidget(
  child: new ClassWidget(),
);

在纸上,两者似乎做的完全一样:创建2 Container,一个嵌套在另一个中。但是实际情况略有不同。

对于函数,生成的窗口小部件树如下所示:

Container
  Container

在使用类时,小部件树为:

ClassWidget
  Container
    ClassWidget
      Container

这很重要,因为它会更改更新小部件时框架的行为。

为什么这么重要

通过使用函数将窗口小部件树拆分为多个窗口小部件,您将面临许多错误,并错过了一些性能优化。

不能保证通过使用函数 遇到错误,但是通过使用类,可以 保证 不会遇到这些问题。

以下是Dartpad上的一些交互式示例,您可以运行这些示例来更好地理解问题:

结论

以下是精选的使用函数和类之间的区别的列表:

  1. 类:

  2. 允许性能优化(const构造函数,更精细的重建)

  3. 确保在两个不同的布局之间切换可以正确处理资源(功能可以重用某些先前的状态)
  4. 确保热装正常(使用功能可能会中断热装等showDialogs
  5. 已集成到小部件检查器中。
    • 我们ClassWidget在devtool所显示的小部件树中看到,这有助于了解屏幕上的内容
    • 我们可以重写debugFillProperties来打印传递给窗口小部件的参数是
  6. 更好的错误消息
    如果发生异常(例如ProviderNotFound),框架将为您提供当前正在构建的小部件的名称。如果仅将小部件树拆分为功能+
    Builder,则错误将没有有用的名称

  7. 可以定义键

  8. 可以使用上下文API

  9. 功能:

  10. 更少的代码(可以使用生成代码的functional_widget来解决)

总体而言,由于这些原因,在类上使用函数来重用窗口小部件被认为是不好的做法。
可以 ,但是将来可能会咬您。

2020-08-13