Flutter状态管理基础知识和有用资源

355 阅读5分钟

Flutter状态管理是一个广泛的主题,可能很难理解这一切。

在本教程中,我将通过解释什么是状态以及本地共享/全局状态之间的区别来帮助您了解基础知识

我还会给你一个概览,介绍你可以用来管理Flutter中的状态的内置部件,以及Flutter官方文档中的最佳资源链接。

你可以走得很远,用内置的Flutter状态管理部件构建非复杂的应用程序。在转向更复杂的解决方案之前,值得学习它们是如何工作的。

在接下来的教程中,我将向你展示如何使用有用的包,如 冻结的, 状态通知器.而且,我还将包括一个完整的指南,介绍 河豚包的完整指南。一路走来,我将介绍重要的状态管理原则Flutter最佳实践,你可以遵循这些原则来编写高质量的代码。

但在我们能跑之前,我们需要学习如何走路。

为此,我们需要了解什么是状态以及Flutter应用程序是如何构建的。

什么是状态?

Flutter应用程序是以声明式编程模型构建的。

这意味着小部件通过重写build() 方法来定义它们的UI,该方法是一个将状态转换为UI的函数。

UI = f(state)

在这种情况下,Flutter文档将状态定义为。

你需要的任何数据,以便在任何时刻重建你的用户界面

我们也可以说,UI是关于你的应用程序的外观。而状态则是关于你的应用程序的行为方式

原则上,这是个简单的概念。

状态 => UI

复杂的是,有许多不同的方法将状态转化为UI,有不同的优点和缺点。

不仅如此,还有两种不同状态:本地状态全局状态

本地状态与全局状态

正如我们所知,我们可以将Flutter小部件组成一个小部件树,代表我们应用程序的用户界面。

Flutter计数器应用示例的部件树

有时候,你有一些状态可以在一个小部件内自成一体。这种状态被称为本地或短暂的状态,Flutter提供了一些内置的工具,如setStateStatefulWidget 来处理这个问题。

如果你有一些简单的状态,只影响一个小部件的行为StatefulWidget ,你就可以了。这个来自Flutter官方频道的视频解释了如何使用它。

另一方面,当状态需要在多个widget甚至整个应用中共享时,你要处理的是共享/全局应用状态

在多个小部件之间共享状态是事情变得有趣的地方,有许多不同的技术可以做到这一点。因此,让我们回顾一下Flutter提供的开箱即用的功能。

继承的部件

您可以使用Flutter内置的InheritedWidget ,在多个widget之间共享状态,正如本视频所解释的。

InheritedWidget 是所有关于使一些数据或状态通过范围内的访问对多个部件可用。例如,在你的widgets里面,你可以调用 来访问主 ,而这在后台使用 。Navigator.of(context) Navigator InheritedWidget

使用InheritedWidget的范围访问

实现你自己的InheritedWidget 子类是不容易的,而且相当容易出错。出于这个原因,引入了提供者包

ValueNotifier & ChangeNotifier

Flutter包括一个ValueNotifier 类,作为在您的widget之外存储您的状态的一种方式。您可以将其与ValueListenableBuilder widget一起使用,以便在状态改变时更新UI。这在这里得到了最好的解释。

这里有一个例子显示了如何一起使用ValueNotifierValueListenableBuilder

final valueNotifier = ValueNotifier<int>(42);

ValueListenableBuilder<int>(
  valueListenable = valueNotifier,
  // called when the value changes
  builder: (context, value, _) {
    return Text('Value is $value')
  }
);

Flutter还附带了ChangeNotifier ,它是ValueNotifier 的 "表亲"。关于如何使用它的实际解释,请看这个页面

FutureBuilder & StreamBuilder

许多异步API使用FuturesStream来通知你的应用程序有新数据可用。

它们的区别在于,Future产生一个单一的异步值,而Stream可以随着时间产生许多异步值。

期货和流都是Dart SDK的一部分。我的《完整的Dart语言》课程非常详细地介绍了它们。

你可以使用Flutter的FutureBuilder widget来决定根据Future的状态**(加载**、数据错误)来显示什么widget。


同样地,使用Flutter的StreamBuilder widget来在流发出新数据时重建你的UI。

当从基于流的API加载异步数据时,检查这些UI状态是很好的做法:数据无数据错误加载

StreamBuilder 构建器支持这一点,但在构建器的 中检查数据或错误是相当笨重的。snapshot

final stream = Stream.fromIterable([21, 42]);

StreamBuilder<int>(
  stream: stream,
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.active) {
      if (snapshot.hasData) {
        return MyWidget(snapshot.data); // data
      } else if (snapshot.hasError) {
        return MyErrorWidget(snapshot.error); // error
      } else {
        return Text('No data'); // no data
      }
    } else {
      return CircularProgressIndicator(); // loading
    }
  }
)

第三方软件包,如flutter_blocProviderRiverpod提供了StreamBuilder 的替代品,使用起来更方便。

使用 Flutter 的内置部件

您可以使用内置的StatelessWidget,StatefulWidget, 和InheritedWidget 类走得很远。你可以使用ChangeNotifierValueNotifier 来管理你的状态,或者在从异步 API 读取数据时使用FutureBuilderStreamBuilder

本官方指南展示了如何使用ChangeNotifierChangeNotifierProvider 把东西放在一起,建立一个简单的购物车应用程序。

总结

我们所涉及的内置小部件是Flutter中状态管理的基础。现在有超过40个状态管理包,但它们都建立在相同的原则和基础上。

所以要花时间通过探索我分享的资源来了解基础知识。

你可以完成Flutter初学者的代码实验来获得一些练习。

如果您想深入挖掘,请查看我的下一个教程。

编码愉快!