StatefulWidget 和 StatelessWidget 的 Flutter 性能

Raf*_*ssi 6 stateful dart flutter

当我必须创建在我的应用程序中多次使用的小部件的“模板”时,我使用了很多 StatelessWidgets,因为文档是这样说的:

当您描述的用户界面部分不依赖于对象本身中的配置信息和小部件在其中膨胀的 BuildContext 之外的任何其他内容时,无状态小部件很有用。

下面是一个例子:

class StepInputButton extends StatelessWidget {

  final int pos;
  final String value;

  const StepInputButton({
    this.pos,
    this.value
  });

  @override
  Widget build(BuildContext context) {
    return Row(
      // Text, Icon and a tiny button
    );
  }

}
Run Code Online (Sandbox Code Playgroud)

以上很好,因为我可以const StepInputButton(val, "val"),在代码中使用 CONST 来提高性能。


问题

我正在使用著名的Provider小部件来管理我的应用程序的状态和页面通常如下所示:

class SuccessPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    var prov = Provider.of<Type>(context);    
    return Scaffold(...); 
  }

}
Run Code Online (Sandbox Code Playgroud)

这是我的带有 Scaffold 的应用程序页面,它有一个抽屉、一个浮动操作按钮和一个 appTitle。在这里,我使用 StatelessWidget,因为我不使用 setState(),因为 provider 为我完成了所有工作。但他们仍然在官方颤振文档中说:

对于可以动态更改的组合,例如由于具有内部时钟驱动状态或取决于某些系统状态,请考虑使用 StatefulWidget。

所以我不得不改变class SuccessPage extends StatelessWidgetclass SuccessPage extends StatefulWidget?我有优势吗?

注意:如果您想以另一种方式提出问题:我应该使用 StatefulWidgets 来创建状态将发生变化的“应用程序页面”,而使用 StatelessWidgets 来创建状态不会改变的“可重用小部件”吗?

Kal*_*ani 7

保持简单:

  1. 如果您的小部件中有final全局变量,那么您需要一个StatefulWidget
  2. 如果所有全局变量都是final那么你应该使用StatelessWidget;

原因:

  1. 如果您的全局变量不是最终变量,则意味着它可以更改,如果它的值发生更改,则意味着您的对象(Widget)的状态发生更改(我正在谈论的基本 oops 概念)。在这种情况下,您需要调用小部件的构建方法,以便将更改应用到 UI 上(如果这对您的 UI 很重要)。我们通过调用来完成此操作setState();,因此我们用于StatefulWidget此类用例。
  2. 如果在构造函数中初始化全局变量就足够了,以后就不需要为它分配任何值,那么在这种情况下使用StatelessWidget.

我试图让它变得非常简单并且技术性不够,因此,如果您仍然有任何疑问,请对此答案发表评论


Abi*_*n47 7

StatefulWidget当小部件本身维护自己的状态时是必需的。在您给出的示例中,Provider包正在为您处理状态,假设您使用的是小部件树更高层的正确提供程序类型(例如,ChangeNotifierProvider)。这段代码中似乎也没有任何内容可以从访问小部件的生命周期中受益,因此您不需要访问像initStateor 之类的方法dispose

因此,小部件本身无需管理任何内容,因此无需将您的类转换为有状态的。

不过,我可能建议的一件事是使用 aConsumer而不是Provider.of直接调用。A 会Consumer为您处理调用,并消除在Provider检测到状态更改时您的小部件是否会更新的任何歧义。


Pet*_*dad 5

您使用StatelessWidget的小部件不会改变其状态,它们将始终保持不变。例如,appBar是无状态的。build(...)的函数StatelessWidget仅被调用一次并且没有任何变化Variable(s)Value(s)或者Event(s)可以再次调用它。

因此,当您需要更改状态(前值)时,请使用StatefulWidgets, 基本上StatelessWidget用于构建静态的 UI 小部件