创建可重用窗口小部件的函数和类有什么区别? [英] What is the difference between functions and classes to create reusable widgets?

查看:102
本文介绍了创建可重用窗口小部件的函数和类有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经意识到,可以使用普通函数来创建小部件,而不是子类化 StatelessWidget 。例如:

I have realized that it is possible to create widgets using plain functions instead of subclassing StatelessWidget. An example would be this:

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

这很有趣,因为它所需的代码少了 而不是成熟的课程。示例:

This is interesting because it requires far less code than a full-blown class. Example:

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

所以我一直想知道:有什么区别吗除了函数和类之间的语法来创建小部件?

So I've been wondering: Is there any difference besides syntax between functions and classes to create widgets? And is it a good practice to use functions?

推荐答案

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

TL;DR: Prefer using classes over functions to make reusable widget-tree.

编辑:要弥补一些误解:
这不是有关导致问题的函数,但类解决了一些问题。

EDIT: To make up for some misunderstanding: This is not about functions causing problems, but classes solving some.

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

Flutter wouldn't have StatelessWidget if a function could do the same thing.

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

Similarly, it is mainly directed at public widgets, made to be reused. It doesn't matter as much for private functions made to be used only once – although being aware of this behavior is still good.

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

There is an important difference between using functions instead of classes, that is: The framework is unaware of functions, but can see classes.

请考虑以下小部件。函数:

Consider the following "widget" function:

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 容器,其中一个嵌套在另一个容器中。但是实际情况略有不同。


On paper, both seem to do exactly the same thing: Create 2 Container, with one nested into the other. But the reality is slightly different.

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

In the case of functions, the generated widget tree looks like this:

Container
  Container

带有类的窗口小部件树为:

While with classes, the widget tree is:

ClassWidget
  Container
    ClassWidget
      Container

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

This is important because it changes how the framework behaves when updating a widget.

使用函数拆分小部件分成多个小部件的树状结构,您可能会遇到一些错误,而错过了一些性能优化。

By using functions to split your widget tree into multiple widgets, you expose yourself to bugs and miss on some performance optimizations.

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

There is no guarantee that you will have bugs by using functions, but by using classes, you are guaranteed to not face these issues.

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

Here are a few interactive examples on Dartpad that you can run yourself to better understand the issues:

https://dartpad.dev/a869b21a2ebd2466b876a5997c9cf3f1

此示例说明了类如何允许对
小部件树进行更细粒度的重建,从而提高了性能

https://dartpad.dev/a869b21a2ebd2466b876a5997c9cf3f1
This example showcases how classes allow more granular rebuilds of the widget tree, improving performances

>://dartpad.dev/06842ae9e4b82fad917acb88da108eee

此示例展示了如何通过使用函数使
暴露于滥用BuildContext并在使用InheritedWidgets(例如Theme或provider)时面临错误

https://dartpad.dev/06842ae9e4b82fad917acb88da108eee
This example showcases how, by using functions, you expose yourself to misusing BuildContext and facing bugs when using InheritedWidgets (such as Theme or providers)

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

Here's a curated list of the differences between using functions and classes:


  1. 类:



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

  • 确保在两个不同布局之间切换可以正确处理资源(函数可以重用某些先前状态)

  • 确保热重装正常工作(使用功能可能会破坏 showDialogs &

  • 已集成到小部件检查器中。

    • 我们在devtool显示的小部件树中看到 ClassWidget ,这有助于了解
      屏幕

    • 我们可以覆盖 debugFillProperties >打印传递给小部件的参数

      • allow performance optimization (const constructor, more granular rebuild)
      • ensure that switching between two different layouts correctly disposes of the resources (functions may reuse some previous state)
      • ensures that hot-reload works properly (using functions could break hot-reload for showDialogs & similar)
      • are integrated into the widget inspector.
        • We see ClassWidget in the widget-tree showed by the devtool, which helps understanding what is on screen
        • We can override debugFillProperties to print what the parameters passed to a widget are

          1. 功能:



          • 具有较少的代码(可以使用代码生成 functional_widget

            • have less code (which can be solved using code-generation functional_widget)
            • 总的来说,由于这些原因,可以在类上使用函数来重用窗口小部件。

              您可以 ,但是将来可能会咬住您。

              Overall, it is considered a bad practice to use functions over classes for reusing widgets because of these reasons.
              You can, but it may bite you in the future.

              这篇关于创建可重用窗口小部件的函数和类有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆