第132期:Flutter中的状态

我心飞翔 分类:vue

状态管理

对于经常写VueReact项目的同学来说,状态管理这个名词并不陌生。同样,在我们开发Flutter应用的时候,我们也需要对状态进行管理。

比如:我们的Flutter应用有两个页面需要共享一个数据,或者父子组件之间需要相互调用之类,我们都可以通过状态管理来处理这些个情况。

声明式的应用

Flutter其实是声明式的。这意味着Flutter会根据我们声明的状态实时的调整UI的布局。这其实跟VueReact很像。

当我们改变了应用的状态,就会触发界面的重绘。我们并没有主动去触发界面UI的变更,就像我们在Vue中没有手动触发html的更新一样,更新了状态,界面就会跟着改变,重新进行绘制。

声明式的代码编写有很多优点,我们只需要在一个地方定义好状态,通过状态来控制UI的展示,只需要定义好状态数据和UI界面的对应关系即可。

应用状态 和 临时状态

从广义上来说,应用状态包括了应用程序运行时内存中所有的状态。这些状态包括:应用的资源、所有的变量、动画的状态、字体等等。

虽然广义上的状态我们是可以理解的,但是这在我们开发应用程序时,作用并不大。

首先,有些状态我们其实是不需要进行处理的,框架本身会对它们进行管理。所以,我们定义状态时,只需要定义跟UI更新相关的状态即可。其次,我们管理自己定义的状态时,这些状态其实是分为应用状态临时状态的。

临时状态(有时称为UI状态或本地状态)是我们定义在单个组件中的状态。这其实也是一个比较模糊的定义,比如:

  • PageView中的current page
  • 复杂动画中的当前进度
  • BottomNavigationBar中当前选中的tab

组件树的其他部分基本上不需要访问这些状态,也不需要进行序列化操作,基本上也不会有复杂的变化。

换句话说,我们不需要用状态管理相关的技术(比如Redux等)对这些状态进行管理,我们只需要用一个StatefulWidget就可以解决问题。

下面这个例子中,_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 ...
    );
  }
}

程序的其他部分不需要访问_index变量,_index只在MyHomepage中进行更改。而且,如果用户关闭并重新启动应用程序,_index将重置为零。

我们希望在应用程序的许多部分共享,并且希望在用户会话之间保持,这种状态就是我们所说的的应用状态(有时也称为共享状态)。比如:

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

对于如何管理应用状态,我们需要研究我们具体的需求。根据所开发应用程序的复杂性、性质、团队以往的经验以及许多其他方面,选择合适的方案进行状态的管理。

如何管理状态

对于如何进行状态的管理,其实并没有一个明确的规则。

我们可以使用StatesetState()来管理应用中的所有状态。但是,有时候随着应用程序规模的不断扩展,有些临时状态就需要在组件之间,或者各种会话之间进行保持,这时候就需要我们选择合适的方案进行处理。

这个关系图可以帮助我们理解这个逻辑:

第132期:Flutter中的状态

image.png

单个组件需要这个状态时,就可以理解它是临时状态。多个组件需要共享这个状态时,它就可以理解为应用状态。

最后

在Flutter的状态管理中,有很多概念我觉得和React以及Vue中的状态管理基本上都是一个道理。

比如:也存在状态提升,都可以用setState()以及Provider进行管理等等。

最后,这篇文章没有什么实质性的技术点,主要是对状态的概念做一个简单的阐述~

回复

我来回复
  • 暂无回复内容