小编典典

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

all

我已经意识到可以使用普通函数而不是继承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
      );
  }
}

所以我一直想知道:除了创建小部件的函数和类之间的语法之外,还有什么区别吗?使用函数是一种好习惯吗?


阅读 71

收藏
2022-05-19

共1个答案

小编典典

编辑 :Flutter
团队现在对此事采取了官方立场,并表示课程更可取。见//www.youtube.com/watch?v=IOyq-eTRhvo)


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. 代码更少(可以使用代码生成功能小部件来解决)

总的来说,由于这些原因,使用函数而不是类来重用小部件被认为是一种不好的做法。
可以 ,但它可能会在未来咬你。

2022-05-19