StatefulWidget 和 StatelessWidget 的 Flutter 性能
Flutter performance of StatefulWidget and StatelessWidget
当我必须创建 "templates" 在我的应用程序中多次使用的小部件时,我使用了很多 StatelessWidgets,因为文档是这样说的:
Stateless widget are useful when the part of the user interface you
are describing does not depend on anything other than the
configuration information in the object itself and the BuildContext in
which the widget is inflated.
这是一个例子:
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
);
}
}
上面的很好,因为我可以在代码中使用 const StepInputButton(val, "val"),
和 CONST 来提高性能。
问题
我正在使用著名的 Provider
小部件来管理状态,我的应用程序页面通常如下所示:
class SuccessPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
var prov = Provider.of<Type>(context);
return Scaffold(...);
}
}
这是我的带有 Scaffold 的应用程序的一个页面,它有一个抽屉、一个浮动操作按钮和一个 appTitle。
在这里,我使用了 StatelessWidget,因为我不使用 setState(),因为提供者为我完成了所有工作。但他们仍然在官方的 flutter 文档中说:
For compositions that can change dynamically, e.g. due to having an
internal clock-driven state, or depending on some system state,
consider using StatefulWidget.
那么我是否必须将 class SuccessPage extends StatelessWidget
更改为 class SuccessPage extends StatefulWidget
?我有优势吗?
注意:如果你想换一种方式提出问题:我应该使用StatefulWidgets来创建状态将要改变的"app pages"和StatelessWidgets "reusable widgets" 谁的状态没有改变?
您将 StatelessWidget
用于不会更改其状态的小部件,这些小部件将始终保持不变。例如,appBar
是无状态的。StatelessWidget
的 build(...)
函数仅被调用一次,并且在任何 Variable(s)
、Value(s)
或 Event(s)
可以再调用。
因此,当您需要更改状态(前值)时,请使用 StatefulWidgets
,基本上 StatelessWidget
用于构建 UI 静态小部件
保持简单:
- 如果您的小部件中有 非
final
全局变量,那么您需要 StatefulWidget
- 如果所有全局变量都是
final
那么你应该使用StatelessWidget
;
原因:
- 如果您的全局变量是非最终变量,则意味着它可以更改,如果它的值发生更改,则意味着您的对象 (Widget) 的状态已更改(我正在谈论的基本 oops 概念)。在这种情况下,您希望调用小部件的构建方法,以便将您的更改应用到 UI(如果它对您的 UI 很重要)。我们通过调用
setState();
来实现,因此我们使用 StatefulWidget
来处理这种用例。
- 如果在构造函数中初始化全局变量就足够了,以后就不需要为它分配任何值,那么在这种情况下使用
StatelessWidget
.
我尽量保持简单和不够专业,所以如果您仍有任何疑问,请评论这个答案。
StatefulWidget
当小部件本身保持其自身状态时是必需的。在您给出的示例中,Provider
包正在为您处理状态,假设您使用的是位于小部件树上方的正确提供程序类型(例如,ChangeNotifierProvider
)。这段代码中似乎也没有任何内容可以从访问小部件的生命周期中获益,因此您不需要访问 initState
或 dispose
等方法。
因此,小部件本身无需管理任何内容,因此无需将 class 转换为有状态的。
不过,我可能建议的一件事是使用 Consumer
而不是直接调用 Provider.of
。 Consumer
为您处理呼叫并消除关于当 Provider
检测到状态更改时您的小部件是否会更新的任何歧义。
当我必须创建 "templates" 在我的应用程序中多次使用的小部件时,我使用了很多 StatelessWidgets,因为文档是这样说的:
Stateless widget are useful when the part of the user interface you are describing does not depend on anything other than the configuration information in the object itself and the BuildContext in which the widget is inflated.
这是一个例子:
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
);
}
}
上面的很好,因为我可以在代码中使用 const StepInputButton(val, "val"),
和 CONST 来提高性能。
问题
我正在使用著名的 Provider
小部件来管理状态,我的应用程序页面通常如下所示:
class SuccessPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
var prov = Provider.of<Type>(context);
return Scaffold(...);
}
}
这是我的带有 Scaffold 的应用程序的一个页面,它有一个抽屉、一个浮动操作按钮和一个 appTitle。 在这里,我使用了 StatelessWidget,因为我不使用 setState(),因为提供者为我完成了所有工作。但他们仍然在官方的 flutter 文档中说:
For compositions that can change dynamically, e.g. due to having an internal clock-driven state, or depending on some system state, consider using StatefulWidget.
那么我是否必须将 class SuccessPage extends StatelessWidget
更改为 class SuccessPage extends StatefulWidget
?我有优势吗?
注意:如果你想换一种方式提出问题:我应该使用StatefulWidgets来创建状态将要改变的"app pages"和StatelessWidgets "reusable widgets" 谁的状态没有改变?
您将 StatelessWidget
用于不会更改其状态的小部件,这些小部件将始终保持不变。例如,appBar
是无状态的。StatelessWidget
的 build(...)
函数仅被调用一次,并且在任何 Variable(s)
、Value(s)
或 Event(s)
可以再调用。
因此,当您需要更改状态(前值)时,请使用 StatefulWidgets
,基本上 StatelessWidget
用于构建 UI 静态小部件
保持简单:
- 如果您的小部件中有 非
final
全局变量,那么您需要StatefulWidget
- 如果所有全局变量都是
final
那么你应该使用StatelessWidget
;
原因:
- 如果您的全局变量是非最终变量,则意味着它可以更改,如果它的值发生更改,则意味着您的对象 (Widget) 的状态已更改(我正在谈论的基本 oops 概念)。在这种情况下,您希望调用小部件的构建方法,以便将您的更改应用到 UI(如果它对您的 UI 很重要)。我们通过调用
setState();
来实现,因此我们使用StatefulWidget
来处理这种用例。 - 如果在构造函数中初始化全局变量就足够了,以后就不需要为它分配任何值,那么在这种情况下使用
StatelessWidget
.
我尽量保持简单和不够专业,所以如果您仍有任何疑问,请评论这个答案。
StatefulWidget
当小部件本身保持其自身状态时是必需的。在您给出的示例中,Provider
包正在为您处理状态,假设您使用的是位于小部件树上方的正确提供程序类型(例如,ChangeNotifierProvider
)。这段代码中似乎也没有任何内容可以从访问小部件的生命周期中获益,因此您不需要访问 initState
或 dispose
等方法。
因此,小部件本身无需管理任何内容,因此无需将 class 转换为有状态的。
不过,我可能建议的一件事是使用 Consumer
而不是直接调用 Provider.of
。 Consumer
为您处理呼叫并消除关于当 Provider
检测到状态更改时您的小部件是否会更新的任何歧义。