Skip to main content

区分短暂状态和应用状态

本文介绍了应用状态、短暂状态以及如何在 Flutter 应用中管理它们。

从最广义的角度来看,应用的状态是在应用运行时内存中存在的一切。这包括应用的资源、Flutter 框架维护的所有关于 UI 的变量、动画状态、纹理、字体等等。虽然这种最广义的状态定义是有效的,但对于构建应用来说并不是很有用。

首先,你甚至无法管理某些状态(例如纹理)。框架会为你处理这些。因此,更有用的状态定义是“在任何时刻重建 UI 所需的任何数据”。其次,你 自己 管理的状态可以分为两种概念类型:短暂状态和应用状态。

短暂状态

#

短暂状态(有时称为_UI 状态 局部状态_)是你可以在单个 Widget 中整齐包含的状态。

这是一个故意模糊的定义,以下是一些示例。

  • PageView 中的当前页面
  • 复杂动画的当前进度
  • BottomNavigationBar 中当前选定的选项卡

Widget 树的其他部分很少需要访问这种状态。无需对其进行序列化,它也不会以复杂的方式发生变化。

换句话说,无需对这种状态使用状态管理技术(ScopedModel、Redux 等)。你只需要一个 StatefulWidget

下面,你将看到底部导航栏中当前选择的项目是如何保存在 _MyHomepageState 类的 _index 字段中的。在这个例子中,_index 是短暂状态。

dart
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 重置为零。

应用状态

#

不是短暂状态,你想在应用的许多部分共享的状态,以及你想在用户会话之间保留的状态,我们称之为应用程序状态(有时也称为共享状态)。

应用状态的示例:

  • 用户偏好设置
  • 登录信息
  • 社交网络应用中的通知
  • 电子商务应用中的购物车
  • 新闻应用中文章的已读/未读状态

为了管理应用状态,你可能需要研究你的选择。你的选择取决于你的应用的复杂性和性质、你团队之前的经验以及许多其他方面。继续阅读。

没有明确的规则

#

需要明确的是,你可以使用 StatesetState() 来管理应用中的所有状态。事实上,Flutter 团队在许多简单的应用示例中就是这样做的(包括你使用每个 flutter create 获取的启动应用)。

反过来也是如此。例如,你可能会决定——在你的特定应用的上下文中——底部导航栏中选定的选项卡 不是 短暂状态。你可能需要从类外部更改它,在会话之间保留它,等等。在这种情况下,_index 变量是应用状态。

没有明确的、普遍的规则来区分特定变量是短暂状态还是应用状态。有时,你必须将一个重构为另一个。例如,你将从一些明显短暂的状态开始,但随着你的应用功能的增长,它可能需要移动到应用状态。

因此,请谨慎看待下图:

流程图。从'数据'开始。'谁需要它?'。三个选项:'大多数 Widget'、'一些 Widget'和'单个 Widget'。前两个选项都指向'应用状态'。'单个 Widget'选项指向'短暂状态'。

当被问及 React 的 setState 与 Redux 的 store 时,Redux 的作者 Dan Abramov 回复道:

“经验法则是:做任何不那么别扭的事情。”

总而言之,任何 Flutter 应用中都有两种概念上的状态类型。短暂状态可以使用 StatesetState() 实现,并且通常位于单个 Widget 中。其余的是你的应用状态。两种类型都在任何 Flutter 应用中都有其位置,两者之间的划分取决于你自己的偏好和应用的复杂性。