Flutter 中的 State
State 的名称是不言自明的“某人或某物在特定时间所处的特定条件”。在我们的应用程序中,这将是应用程序启动时加载到内存中的所有应用程序信息,如 Assets, Resources, UI 等。然而,当我们谈论 State 管理时,我们并不是指管理这个 State ,因为 Flutter 在内部对此进行了管理。
我们关注的 State 是流经应用程序的数据。可以从应用程序的任何部分对其进行更新、收听、修改等。
State:随时重建 UI 所需的任何数据。
我们可以将 State 分为两种类型:
- 临时状态
- 应用状态
Flutter 中的临时状态
临时状态也称为本地状态或 UI 状态,因为它仅与 widget 相关。这种 State 不需要 State 管理,使用一个 Simple Stateful Widget 就足够了。临时状态的一些例子是:
- PageView 中的选定页面索引
- TabView 或 BottomNavigtionBar 中的选定选项卡索引
class HomePage extends StatefulWidget {
// Create a class that extnds Stateful Widget
const HomePage({Key? key}) : super(key: key);
@override
_HomepageState createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
// Define The Variable as private field in the State class
int _currentPage = 0;
@override
Widget build(BuildContext context) {...}
void updateCurrentPage(int value){
// Call setState when updating values
_currentPage = value;
setState((){});
}
}
不需要 State 管理,因为整个页面需要在 PageView 页面更改时重建。请注意,_currentPage 是仅在此 widget 中需要的属性。
Flutter 中的应用状态
跨多个 widget 或应用程序的多个部分共享的状态称为应用程序状态。自然也称为共享状态。这是 State 管理解决方案要解决的问题。应用状态的一些示例是:
- 电子商务应用程序的购物车
- 登录和身份验证详细信息
- 用户偏好和设置
在下图中,可以看到如何将数据分类为 Ephemeral 和 App State。
为什么在 Flutter 项目中需要 State 管理?
在小型应用程序中,数据仅限于某些 widget ,setState((){}) 足以管理 State 。但是,随着应用程序的扩展,将需要跨多个 widget 共享和操作数据。这就是你意识到你需要一种 State 管理技术的时候。
有许多选项可用,但基本思想很常见,即跨多个 widget 共享数据。使用良好的 State 管理技术还可以帮助分离后端和前端逻辑。因此,代码库变得可维护和可读。
状态管理技术
我们这里的主要问题是我们必须跨多个页面传递依赖关系。即使我们将数据集中为全局,我们仍然无法获取 widget 树中数据的更新。所以我们可以做的一件基本的事情是依赖注入。 Flutter 中的一个原生解决方案是使用 Inherited Widget。
Inherited Widget 有效地将信息沿树传播。
虽然这种方法解决了我们的问题,但我们在使用 Inherited Widget 时仍然存在一些问题。一个主要问题是每个 Inherited Widget 附带的样板代码。为了解决这个特定问题,Rémi Rousselet 创建了 Provider。然而,Provider 在后台使用了 Inherited Widget,这使得实现变得非常容易。
Provider:InheritedWidget 的包装器,使它们更易于使用和更可重用。
Provider 对于 Flutter 中的 State 管理来说绰绰有余,但由于一些限制,他们创建了一个新版本的 Provider。 Provider 本身的作者(Rémi Rousselet)介绍了 RiverPod。 RiverPod 是 Provider 的改进版本。现在我们不会遇到任何运行时错误,我们会在运行时本身收到所有错误。此外,它不依赖于 Flutter,因此不需要构建上下文来监听提供者,现在也可以在 Dart 项目中使用 RiverPod。
RiverPod 对于中小型项目来说已经足够了。然而,大型项目需要的不仅仅是 State 管理,这是一个以 BoilerPlate 代码为代价的干净架构。一些大型项目的状态管理解决方案有 BLoC、Redux、MobX、GetX 等。但是,这些解决方案仅适用于大型项目,在小型项目中,这会导致大量样板,从而导致混乱。
因此,对于中小型项目,RiverPod 结合 ValueNotifier 和 ChangeNotifier 可以满足大多数项目的 State 管理需求。
结论
在这篇文章中,我们了解了 Flutter 中 State 的基础知识。我们讨论了 Flutter 中的 Ephemeral 和 App State 以及为管理 Flutter 中的 State 而提供的解决方案。