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上的一些交互式示例,您可以运行这些示例来更好地理解问题:
https://dartpad.dev/1870e726d7e04699bc8f9d78ba71da35
此示例展示了如何通过将应用拆分为功能来意外破坏诸如AnimatedSwitcher
https://dartpad.dev/a869b21a2ebd2466b876a5997c9cf3f1
此示例展示了类如何允许对小部件树进行更细粒度的重建,从而提高了性能https://dartpad.dev/06842ae9e4b82fad917acb88da108eee
此示例展示了如何通过使用函数使自己暴露于滥用BuildContext并在使用InheritedWidgets(例如Theme或provider)时面临错误。
结论
以下是精选的使用函数和类之间的区别的列表:
类:
允许性能优化(const构造函数,更精细的重建)
- 确保在两个不同的布局之间切换可以正确处理资源(功能可以重用某些先前的状态)
- 确保热装正常(使用功能可能会中断热装等
showDialogs
) - 已集成到小部件检查器中。
- 我们
ClassWidget
在devtool所显示的小部件树中看到,这有助于了解屏幕上的内容 - 我们可以重写debugFillProperties来打印传递给窗口小部件的参数是
- 我们
更好的错误消息
如果发生异常(例如ProviderNotFound),框架将为您提供当前正在构建的小部件的名称。如果仅将小部件树拆分为功能+Builder
,则错误将没有有用的名称可以定义键
可以使用上下文API
功能:
更少的代码(可以使用生成代码的functional_widget来解决)
总体而言,由于这些原因,在类上使用函数来重用窗口小部件被认为是不好的做法。
您 可以 ,但是将来可能会咬您。



