简体   繁体   English

setState 是否为 flutter 中的屏幕重建整个小部件树以及它与其他 State 管理相比如何

[英]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 setState() is called from widgetB, are WidgetA, B, and C rebuilt?如果从 widgetB 调用 setState(),是否重建 WidgetA、B 和 C?
  • how does this compare to using different state Management techniques like State provider, stream builders, or Bloc?这与使用不同的 state 管理技术(如 State 提供程序、stream 构建器或 Bloc)相比如何?
  • when to use setState()?何时使用 setState()?
  • is it smart to combine multiple State management techniques?组合多种 State 管理技术是否明智?

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:按顺序回答您的问题:

  1. 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小部件。

  2. Using the BLoC approach, most of the times it's optional to use Stateful Widgets and setState() to manage State.使用BLoC方法,大多数时候可以选择使用Stateful WidgetssetState()来管理 State。 In this approach you'll use events from the UI , which will be converted into 'States' inside your BLoC.在这种方法中,您将使用来自UIevents ,这些事件将在您的 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重建自身及其后代。

  3. If you're using BLoC or Provider + Streams , I would recommend avoiding setState() and StatefulWidgets , maybe with some exceptions like UI things, eg.如果您使用BLoCProvider + Streams ,我建议您避免使用setState()StatefulWidgets ,可能会有一些例外情况,例如 UI 内容,例如。 animations.动画。

  4. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM