[英]Does setState rebuild the whole widget tree for a screen in flutter and how does it compare with other State management
I'm kinda confused, I have been looking into state management with flutter recently and I was wondering what happens if a custom stateful widget is placed in a stateless widget, let's say widgetA (parent) is a stateless widget and it has a child WidgetB which is a stateful widget and another child WidgetC which is a stateless widget.我有点困惑,我最近一直在使用 flutter 研究 state 管理,我想知道如果将自定义有状态小部件放置在无状态小部件中会发生什么,假设 widgetA(父)是一个无状态小部件并且它有一个子 WidgetB这是一个有状态的小部件,另一个子 WidgetC 是一个无状态的小部件。
Now my questions are:现在我的问题是:
if you have external links or resources that can help me understand please provide them如果您有可以帮助我理解的外部链接或资源,请提供
If I say something wrong, someone please correct me.如果我说错了,请有人纠正我。
Answering your questions in order:按顺序回答您的问题:
If you call setState()
on WidgetB
it'll rebuild itself and it's descendants, no matter if they are Stateless
or Stateful
Widgets.如果您在
WidgetB
上调用setState()
,它将重新构建自身及其后代,无论它们是Stateless
状态小部件还是Stateful
小部件。
Using the BLoC approach, most of the times it's optional to use Stateful Widgets
and setState()
to manage State.使用BLoC方法,大多数时候可以选择使用
Stateful Widgets
和setState()
来管理 State。 In this approach you'll use events
from the UI , which will be converted into 'States' inside your BLoC.在这种方法中,您将使用来自UI的
events
,这些事件将在您的 BLoC 中转换为“状态”。 This States will be passed into a Stream.这些状态将被传递到 Stream。 Your UI will rebuild itself using
StreamBuilders
every time they listen to a new value on the Stream they're listening.您的UI将在每次他们正在收听的 Stream 上收听新值时使用
StreamBuilders
重新构建自己。 This will trigger the StreamBuilder
to rebuilt itself and it's descendants.这将触发
StreamBuilder
重建自身及其后代。
If you're using BLoC
or Provider
+ Streams
, I would recommend avoiding setState()
and StatefulWidgets
, maybe with some exceptions like UI things, eg.如果您使用
BLoC
或Provider
+ Streams
,我建议您避免使用setState()
和StatefulWidgets
,可能会有一些例外情况,例如 UI 内容,例如。 animations.动画。
BLoC is a design approach with goes nice with the Provider package
. BLoC 是一种与
Provider package
配合得很好的设计方法。 The BLoC package
even uses Provider
internally. BLoC package
甚至在内部使用了Provider
。
PS: Whereas BLoC
is an Architecture Pattern to manage the Data and State of your application. PS:而
BLoC
是一种架构模式,用于管理应用程序的数据和 State。 Provider is 'just' a wrapper around Inherited Widgets
that facilitate exposure of Data throughout your Widget tree, not an Architecture Pattern.提供者“只是”一个围绕
Inherited Widgets
的包装器,它有助于在整个小部件树中公开数据,而不是架构模式。
Other example of architecture pattern solution to manage state that uses the provider
package is MobX
.管理使用
provider
package 的 state 的架构模式解决方案的其他示例是MobX
。
setState() will call the build() method and rebuilds with widget tree (With Flutter optimizations under the hood), if you wish to build only a part there is an Alternative: create a Provider that holds the change that you want to reflect in the UI, and wrap that widget with a Consumer - when you will call notifyListener() from the Provider only that Widget will rebuild. setState() 将调用 build() 方法并使用小部件树进行重建(使用 Flutter 优化),如果您只想构建一个部分,则有一个替代方案:创建一个包含您想要反映的更改的提供程序UI,并用消费者包装该小部件 - 当您从提供者调用 notifyListener() 时,只有该小部件将重建。
For Example:例如:
child: Consumer<MessageIconStateProvider>(
builder: (context, messageIconProvider, child) {
return Container(
height: 40,
child: messageIconProvider.isShowMessageIcon
? Icon(
Icons.send,
size: 24,
color: Colors.white,
)
: Icon(
Icons.mic_outlined,
size: 24,
color: Colors.white,
),
);
}
)
The provider:提供者:
import 'package:flutter/material.dart';
class MessageIconStateProvider with ChangeNotifier {
var isShowMessageIcon = true;
void setIconToMessage(bool setIconToMessage){
if(setIconToMessage != isShowMessageIcon) {
isShowMessageIcon = setIconToMessage;
notifyListeners();
}
}
}
And don't forget to define it on your main.dart file:不要忘记在 main.dart 文件中定义它:
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => MessageIconStateProvider()),
],...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.