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

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

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. 课程:
  • 允许性能优化(const 构造函数,更精细的重建)
  • 确保在两种不同布局之间切换正确处理资源(函数可能会重用某些先前的状态)
  • 确保热重载正常工作(使用函数可能会破坏showDialogs类似的热重载)
  • 被集成到小部件检查器中。
    • 我们ClassWidget在 devtool 显示的小部件树中看到,这有助于理解屏幕上的内容
    • 我们可以覆盖debugFillProperties来打印传递给小部件的参数是什么
  • 更好的错误消息 如果发生异常(如 ProviderNotFound),框架将为您提供当前正在构建的小部件的名称。如果您仅在函数 + 中拆分小部件树Builder,您的错误将没有有用的名称
  • 可以定义键
  • 可以使用上下文 API
  1. 职能:

总的来说,由于这些原因,在类上使用函数来重用小部件被认为是一种不好的做法。