Flutter状态管理是一个广泛的主题,可能很难理解这一切。
在本教程中,我将通过解释什么是状态以及本地和共享/全局状态之间的区别来帮助您了解基础知识。
我还会给你一个概览,介绍你可以用来管理Flutter中的状态的内置部件,以及Flutter官方文档中的最佳资源链接。
你可以走得很远,用内置的Flutter状态管理部件构建非复杂的应用程序。在转向更复杂的解决方案之前,值得学习它们是如何工作的。
在接下来的教程中,我将向你展示如何使用有用的包,如 冻结的, 状态通知器.而且,我还将包括一个完整的指南,介绍 河豚包的完整指南。一路走来,我将介绍重要的状态管理原则和Flutter最佳实践,你可以遵循这些原则来编写高质量的代码。
但在我们能跑之前,我们需要学习如何走路。
为此,我们需要了解什么是状态以及Flutter应用程序是如何构建的。
什么是状态?
Flutter应用程序是以声明式编程模型构建的。
这意味着小部件通过重写build() 方法来定义它们的UI,该方法是一个将状态转换为UI的函数。
UI = f(state)
在这种情况下,Flutter文档将状态定义为。
你需要的任何数据,以便在任何时刻重建你的用户界面
我们也可以说,UI是关于你的应用程序的外观。而状态则是关于你的应用程序的行为方式。
原则上,这是个简单的概念。
状态 => UI
复杂的是,有许多不同的方法将状态转化为UI,有不同的优点和缺点。
不仅如此,还有两种不同的状态:本地状态和全局状态。
本地状态与全局状态
正如我们所知,我们可以将Flutter小部件组成一个小部件树,代表我们应用程序的用户界面。
Flutter计数器应用示例的部件树
有时候,你有一些状态可以在一个小部件内自成一体。这种状态被称为本地或短暂的状态,Flutter提供了一些内置的工具,如setState 和StatefulWidget 来处理这个问题。
如果你有一些简单的状态,只影响一个小部件的行为,StatefulWidget ,你就可以了。这个来自Flutter官方频道的视频解释了如何使用它。
另一方面,当状态需要在多个widget甚至整个应用中共享时,你要处理的是共享/全局应用状态。
在多个小部件之间共享状态是事情变得有趣的地方,有许多不同的技术可以做到这一点。因此,让我们回顾一下Flutter提供的开箱即用的功能。
继承的部件
您可以使用Flutter内置的InheritedWidget ,在多个widget之间共享状态,正如本视频所解释的。
InheritedWidget 是所有关于使一些数据或状态通过范围内的访问对多个部件可用。例如,在你的widgets里面,你可以调用 来访问主 ,而这在后台使用 。Navigator.of(context) Navigator InheritedWidget
使用InheritedWidget的范围访问
实现你自己的
InheritedWidget子类是不容易的,而且相当容易出错。出于这个原因,引入了提供者包。
ValueNotifier & ChangeNotifier
Flutter包括一个ValueNotifier 类,作为在您的widget之外存储您的状态的一种方式。您可以将其与ValueListenableBuilder widget一起使用,以便在状态改变时更新UI。这在这里得到了最好的解释。
这里有一个例子显示了如何一起使用ValueNotifier 和ValueListenableBuilder 。
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使用Futures和Stream来通知你的应用程序有新数据可用。
它们的区别在于,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_bloc、Provider和Riverpod提供了
StreamBuilder的替代品,使用起来更方便。
使用 Flutter 的内置部件
您可以使用内置的StatelessWidget,StatefulWidget, 和InheritedWidget 类走得很远。你可以使用ChangeNotifier 或ValueNotifier 来管理你的状态,或者在从异步 API 读取数据时使用FutureBuilder 和StreamBuilder 。
本官方指南展示了如何使用ChangeNotifier 和ChangeNotifierProvider 把东西放在一起,建立一个简单的购物车应用程序。
总结
我们所涉及的内置小部件是Flutter中状态管理的基础。现在有超过40个状态管理包,但它们都建立在相同的原则和基础上。
所以要花时间通过探索我分享的资源来了解基础知识。
你可以完成Flutter初学者的代码实验来获得一些练习。
如果您想深入挖掘,请查看我的下一个教程。
编码愉快!