区分短暂状态和应用状态
本文介绍了应用状态、短暂状态以及如何在 Flutter 应用中管理它们。
从最广义的角度来看,应用的状态是在应用运行时内存中存在的一切。这包括应用的资源、Flutter 框架维护的所有关于 UI 的变量、动画状态、纹理、字体等等。虽然这种最广义的状态定义是有效的,但对于构建应用来说并不是很有用。
首先,你甚至无法管理某些状态(例如纹理)。框架会为你处理这些。因此,更有用的状态定义是“在任何时刻重建 UI 所需的任何数据”。其次,你 自己 管理的状态可以分为两种概念类型:短暂状态和应用状态。
短暂状态
#短暂状态(有时称为_UI 状态 或 局部状态_)是你可以在单个 Widget 中整齐包含的状态。
这是一个故意模糊的定义,以下是一些示例。
PageView
中的当前页面- 复杂动画的当前进度
BottomNavigationBar
中当前选定的选项卡
Widget 树的其他部分很少需要访问这种状态。无需对其进行序列化,它也不会以复杂的方式发生变化。
换句话说,无需对这种状态使用状态管理技术(ScopedModel、Redux 等)。你只需要一个 StatefulWidget
。
下面,你将看到底部导航栏中当前选择的项目是如何保存在 _MyHomepageState
类的 _index
字段中的。在这个例子中,_index
是短暂状态。
class MyHomepage extends StatefulWidget {
const MyHomepage({super.key});
@override
State<MyHomepage> createState() => _MyHomepageState();
}
class _MyHomepageState extends State<MyHomepage> {
int _index = 0;
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
currentIndex: _index,
onTap: (newIndex) {
setState(() {
_index = newIndex;
});
},
// ... items ...
);
}
}
在这里,使用 setState()
和 StatefulWidget
状态类内部的字段是完全自然的。你的应用的其它部分不需要访问 _index
。该变量只在 MyHomepage
Widget 内部更改。而且,如果用户关闭并重新启动应用,你不会介意 _index
重置为零。
应用状态
#不是短暂状态,你想在应用的许多部分共享的状态,以及你想在用户会话之间保留的状态,我们称之为应用程序状态(有时也称为共享状态)。
应用状态的示例:
- 用户偏好设置
- 登录信息
- 社交网络应用中的通知
- 电子商务应用中的购物车
- 新闻应用中文章的已读/未读状态
为了管理应用状态,你可能需要研究你的选择。你的选择取决于你的应用的复杂性和性质、你团队之前的经验以及许多其他方面。继续阅读。
没有明确的规则
#需要明确的是,你可以使用 State
和 setState()
来管理应用中的所有状态。事实上,Flutter 团队在许多简单的应用示例中就是这样做的(包括你使用每个 flutter create
获取的启动应用)。
反过来也是如此。例如,你可能会决定——在你的特定应用的上下文中——底部导航栏中选定的选项卡 不是 短暂状态。你可能需要从类外部更改它,在会话之间保留它,等等。在这种情况下,_index
变量是应用状态。
没有明确的、普遍的规则来区分特定变量是短暂状态还是应用状态。有时,你必须将一个重构为另一个。例如,你将从一些明显短暂的状态开始,但随着你的应用功能的增长,它可能需要移动到应用状态。
因此,请谨慎看待下图:
![流程图。从'数据'开始。'谁需要它?'。三个选项:'大多数 Widget'、'一些 Widget'和'单个 Widget'。前两个选项都指向'应用状态'。'单个 Widget'选项指向'短暂状态'。](/assets/images/docs/development/data-and-backend/state-mgmt/ephemeral-vs-app-state.png)
当被问及 React 的 setState 与 Redux 的 store 时,Redux 的作者 Dan Abramov 回复道:
“经验法则是:做任何不那么别扭的事情。”
总而言之,任何 Flutter 应用中都有两种概念上的状态类型。短暂状态可以使用 State
和 setState()
实现,并且通常位于单个 Widget 中。其余的是你的应用状态。两种类型都在任何 Flutter 应用中都有其位置,两者之间的划分取决于你自己的偏好和应用的复杂性。
除非另有说明,否则本网站上的文档反映的是 Flutter 的最新稳定版本。页面最后更新于 2025-01-30。 查看源代码 或 报告问题。