Flutter 状态管理引子

1、为了更好地了解状态管理,先看看什么是状态。

在类似Flutter这样的响应式编程框架中,我们可以认为U相关的开发就是对数据进行封装,将之转换为具体的U1布局或者组件。借用Flutter官网的一张图,可以把我们在第二部分做的所有开发都抽象为下图所示的过程。

2、状态即为数据

Flutter框架通过build方法,將我们拥有的"数据",也就是状态转换成了具体的页面内容,Fiutter官方将这些状态划分为了两种不同的类型:短时(ephemeral) 状态与应用(app)状态。所谓短时状态,是指包含在单个widget中且不会与其他widget共享的状态;应用状态则相反,是指会在多个Widget之间共享的状态。没太明白?没关系,这里我们只要理解"状态即为数据"就可以了。

3、响应式编程与命令式编程

传统的GUI编程框架(例如iOS的UIKit和 Android的SDK) 都属于命令式编程风格。所谓命令式编程,是指需要使用类似button.text="hello world"

这样的方式来修改一个按钮上的文本。命令式编程的好处在于代码比较直观且易于理解,问题在于开发者很难将众多命令式的代码和实际的用户界面关联起来。而Flutter这种响应式编程框架很好地解决了这个问题,在响应式编程框架中,可以很容易地将代码与实际的用户界面关联起来(例如,Flutter中的build方法里的代码很容易就可以和实际的用户界面相关联),只是在响应式编程框架中,我们一般不会直接通过获取button对象的方式修改按钮上的文本,而是通过修改button对象对应的"状态"来修改,即框架替我们完成了修改状态后,更新button对象的工作。

4、维基百科-状态管理定义

〝状态管理指的是在图形用户界面中,对于和用户界面中类似文本框、按钮这样的组件所对应的状态的管理方式。,...尤其指代某个页面需要和其他多个页面共享状态的场景一一维基百科"

根据维基百科的定义,我们不难得出,状态管理面临的问题其实就是如何在复杂的页面中管理大规模,尤其是跨页面(或者说在Flutter中跨widget)的数据共享。从逻辑上讲,可以将Flutter中跨widget的状态共享分成下图中的三种情况。
在状态管理的范畴中,解决widget之间状态共享问题的通用思路也很简单单一一提高状态的层级。也就是说,如果widget之间需要共享状态,就把这个状态提升到这两个widget的共同祖先widget中,将这个短时状态转变为应用状态。

4、结论

总而言之,得出这样一个结论:Flutter中状态管理所要解决的最根本的问题,就是如何在任意一个widget中获取某一个应用状态。接下来,我们会逐步分析如何在Flutter的框架体系中解决这个问题。

5、Flutter中的状态管理

在不引入任何新概念的前提下,要想从子Widget获取其父Widget中的状态,有以下两种简单的实现方式:

    1. 通过构造方法将父widget中的状态传递给子Widget;
    1. 把父widget的状态层级大幅度提高,使该状态成为一个全局的单例对象,在任何地方都可以获取到它。

6、5中的缺点

在业务逻辑比较简单的情况下,使用这两种方式都不会出现太多的问题,可是一旦业务逻辑变得复杂,这两种方式就有可能力不从心了。

  • 1.针对第一种方式,如果需要跨越多个层级传递数据,那么可以想象得到,对于整个层级的每一个widget中的构造方法,都需要添加对应的构造参数,需要跨越的层级越深,我们的代码就越丑陋。
  • 2.对于第二种方式,当需要共享的状态仅和个别页面相关联时,全局的单例对象会导致很多额外的开销。例如,我们可能只需要在某个子页面记录某个按钮是否可用,如果用一个单例对象存储按钮是否可用的状态,那么在页面被销毁后,还需要销毁单例对象中存储的对应状态对应,否则单例对象中会存在很多这样的无用状态。

以上两种方式,虽然在具体实现中都出现了问题,,但这些问题其实并不是方式方面的问题,而只是代码工程化方面的。

实际上,Flutter官方推荐的状态管理实现方式基本上就是基于这两种方式的工程化优化和实现。

7、原理

inheritedwidget和inheritedModel正是对第一种方式的工程化优化,Provider和Scoped Model则是对inherited widget的AP1封装,让我们能够少写一些重复度比较高的代码。BIoC仅仅是提供了一个组织逻辑代码和U代码的思路,其实际实现--flutter_bloc则是基于Provider包实现的。RxDart只是修改了B1oC中一部分

逻辑代码的编写方式,并没有在机制上逃出Inheritedwidget的范畴。Redux的层次和BIoC类似,只是给出了一个组织代码的方式和思路,它的一个实际实现一---fish_redux中也是利用inheriteawidget实现的。

8、如何使用Inherited Widget,和其原理

后续补充

9、使用Provider包完成状态管理

主流

相关推荐
Jinkey5 小时前
FlutterBasic - GetBuilder、Obx、GetX<Controller>、GetxController 有啥区别
android·flutter·ios
Summer不秃9 小时前
Flutter之使用mqtt进行连接和信息传输的使用案例
前端·flutter
旭日猎鹰9 小时前
Flutter踩坑记录(二)-- GestureDetector+Expanded点击无效果
前端·javascript·flutter
sunly_9 小时前
Flutter:AnimatedSwitcher当子元素改变时,触发动画
flutter
AiFlutter9 小时前
Flutter封装Coap
flutter
旭日猎鹰15 小时前
Flutter踩坑记录(三)-- 更改入口执行文件
flutter
旭日猎鹰15 小时前
Flutter踩坑记录(一)debug运行生成的项目,不能手动点击运行
flutter
️ 邪神15 小时前
【Android、IOS、Flutter、鸿蒙、ReactNative 】自定义View
flutter·ios·鸿蒙·reactnative·anroid
比格丽巴格丽抱1 天前
flutter项目苹果编译运行打包上线
flutter·ios
SoaringHeart1 天前
Flutter进阶:基于 MLKit 的 OCR 文字识别
前端·flutter