【问题标题】:Why do we need stateless widgets if the same can be achieved by stateful widgets in flutter?如果 Flutter 中的有状态小部件可以实现同样的功能,为什么我们还需要无状态小部件?
【发布时间】:2023-04-08 02:09:01
【问题描述】:

我是 Flutter 领域的新手,我最近了解了(或者我认为我了解了)有状态和无状态小部件,这是 Flutter 小部件的基础。

我们将无状态小部件用于未在显示屏上重绘的内容(如文本、按钮等),但有状态小部件可以自行重绘。

所以我的问题是,如果有状态小部件可以用来绘制与无状态小部件相同的小部件,为什么我们还需要无状态小部件?

或者在颤振中使用无状态而不是有状态小部件是否有任何具体原因?或者我们可以一直使用有状态的小部件,而不是只能绘制一次内容的无状态小部件?

谢谢,如果这是一个愚蠢的问题,对不起。

编辑

问题不在于无状态和有状态之间的区别。 我知道区别,但是只使用有状态小部件有什么影响,因为通过使用它,我们还可以实现无状态小部件可以做的大部分事情,那么为什么我们需要无状态小部件?它在颤振环境中的重要性是什么?的应用程序将不时重新绘制?

【问题讨论】:

  • 我现在也在学习 Flutter,我认为与无状态小部件相比,Flutter 必须做一些额外的工作来管理有状态小部件。这里可能需要专家的意见。
  • 是的,我觉得很奇怪。如果有一个可以重绘屏幕的小部件,那么我们可以使用它而不是只能绘制一次的小部件,对吧?
  • 我认为无状态小部件是轻量级的,因为当您调用 setState() 时它们不需要刷新/重新生成。这就是为什么当你认为任务可以由无状态小部件完成时,你应该使用它们。
  • 这个问题有正确答案吗?
  • 基本上不是,问题回答了差异是的,但不是我的问题完全

标签: flutter statefulwidget statelesswidget


【解决方案1】:

是的,StatefulWidget 可以重建。这通常在使用 Inheritedwidgets 时发生。

StatelessWidget 的存在是为了将大的小部件树拆分成更小的可重用小部件。

您可能会想“但我可以为此使用 StatefulWidget 或函数”。这是真的,但不完全是:

  • StatefulWidget 带有一个巨大的样板文件,在这种情况下您不需要它。因此,这只会增加噪音并使您的代码可读性降低。
  • 函数不能独立重建,也不能访问key 和覆盖==。因此它们的性能可能会降低或引入错误。

【讨论】:

    【解决方案2】:

    来自他们的documentation

    无状态小部件在您描述的用户界面部分不依赖于对象本身中的配置信息和小部件膨胀所在的 BuildContext 以外的任何内容时很有用。 (= 当您不需要“在此处更新 UI”时使用)。

    有状态小部件更消耗资源,您始终需要考虑性能。

    Here is more about this.

    将状态推送到叶子。例如,如果您的页面有一个滴答声 时钟,而不是将状态放在页面顶部 每次时钟滴答时重建整个页面,创建一个 只更新自身的专用时钟小部件。

    Even more on this :)

    我希望这能回答你的问题。

    【讨论】:

    • 但是有没有不偶尔重绘的应用?如果是这种情况,那么大多数小部件都是有状态的,对吧?
    • 当然他们会重绘,但关键是要让应用程序尽可能流畅,你可以做到这一点的一种方法是在调用 setState 时减少构建。也许在“强大”设备上运行的一些“轻量级”屏幕上看起来一切都很好,但是当这种情况发生变化时,您可能会遇到一些不太好的用户界面(缓慢/生涩/无响应)
    • 所以我们不能假设随着时间的推移有状态的小部件被优化,那么我们只能使用有状态的小部件而不是无状态的,对吧?
    • 即便如此,当您不需要或使用它时,为什么还要在小部件上使用开销(状态对象)?是的,你可以每次都使用有状态而不是无状态,但这违反了 KISS 或任何其他干净的代码准则。您将拥有永远不会使用的东西,这通常是一个不好的迹象。
    【解决方案3】:

    每次我们使用 Stateful 小部件时,都会创建一个状态对象。如果我们使用所有 Stateful 小部件,将会有很多不必要的状态对象,它们会消耗大量内存。所以在我们不需要改变状态的地方,我们应该使用更简单的——Stateless小部件。

    使用 Stateless 小部件而不是 Stateful 小部件的另一个原因是 Stateful 小部件带有一个巨大的样板文件,并且根据 Flutter API 文档 使用一堆嵌套的 Stateful 小部件,通过所有这些构建方法和构造函数传递数据会变得很麻烦。

    【讨论】:

      【解决方案4】:

      这是我的理解……

      当您使用有状态小部件并重绘它时,内部的所有其他小部件也将被重绘。所以我们尝试使用无状态小部件,以免重绘其中的其他小部件,但您知道我们通常需要更改屏幕上的数据,它应该发生在“单个小部件”内,并且这个小部件应该是一个有状态的小部件尽可能少地使用计算能力。

      现在......我猜你在想:“但是如果我只使用有状态的小部件而不重绘它们怎么办?”好吧,如您所知,当您使用有状态小部件时,您有两个类:小部件和状态。我已经知道,当您声明一个状态时,您会告诉手机无论是否重绘小部件,都要将此状态保留并保存在内存中,因此您无缘无故地使用手机内存,因为您不需要重绘其小部件。

      我们应该考虑始终使用无状态小部件,因为它们比有状态小部件更轻,并且我们应该始终使有状态小部件在我们的应用程序中最小,以便在应用程序的小部件树中尽可能少地重绘小部件。

      希望我能帮上一点忙。

      【讨论】:

        猜你喜欢
        • 2018-09-01
        • 2021-12-15
        • 2021-05-30
        • 2021-07-12
        • 1970-01-01
        • 2019-09-23
        • 2021-05-03
        • 2019-06-10
        • 2021-05-19
        相关资源
        最近更新 更多