为了了解Flutter的状态管理,我以10种方式修改了柜台App
浏览:294 次
本文通过修改Flutter的计数器App,展示了不同状态管理方法的用法
您可以直接转到演示地址查看代码:
切换分支对应不同的实现方法
目录
颤振状态管理
状态分类
状态管理方法概述
计数器示例的默认实现:StatefulWidget
继承的小部件
范围模型
供应商
集团
BLoC手动实施
通过BLOC+InheritedWidget传输
BLoC rxdart实现
BLoC库实现
rx零件
重做(Redux)
移动X
颤振挂钩
演示说明和想法
颤振状态管理
颤动是描述性的,UI反映了状态
UI=f(状态)
其中,f表示构建方法
状态更改将直接触发UI重绘
UI对更改做出反应。
相比之下,Android、iOS等是必不可少的,并且将有setText()和其他方法来更改UI
状态分类
有两种状态:
短暂状态:有时称为UI状态或本地状态这可以包含在单个小部件中
例如,PageView的当前页面、动画的当前进度以及BottomNavigationBar的当前选定选项卡

该状态不需要使用复杂的状态管理方法,只需使用有状态的小部件
App状态:需要在多个地方共享的状态,也称为共享状态或全局状态
例如:用户设置、登录信息、通知、购物车、新闻App中的已读/未读状态等
事实上,这种状态分类没有明确的界限
在一个简单的App中,您可以使用setState()来管理所有状态;当应用需要时,标签索引也可以从外部提取,作为要保存和管理的应用状态
状态管理方法
官方提供了一些选项:
目前,官方推荐为供应商
各种状态管理方法需要解决的几个问题:
州保存在哪里?
如何获取状态?
UI如何更新?
如何更改状态?
计数器示例默认实现:StatefulWidget
一个新的FlutterApp是一个计数器App,它自动使用Stateful Widgets来管理状态
这对于这个简单的App来说是合理的
我们对App进行了简单的转换,并添加了一个减法按钮
同样,只需添加一个减法
此方法的一个变体是使用Stateful Builder。主要优点是编写更少的代码
有状态的小部件对于简单的小部件内部状态来说是合理的
对于复杂状态,该方法的缺点是:
有许多状态属性后,可以在许多地方调用setState()
状态和UI不能单独管理
这不利于跨组件/跨页面状态共享(如何调用另一个小部件的setState()?通过施工转移方法?不,不要这样做!)
永远不要使用全局变量来解决问题
如果您试图以这种方式管理跨组件状态,您将不可避免地使用这些反模式:
紧密耦合强耦合小部件。
全局保存状态全局跟踪状态。
从外部调用setState方法从外部调用setState。
因此,该方法仅适用于地方州管理
代码分支1:
代码分支2:

继承的小部件
Widget树的主要功能是有效地传递信息
如果没有InheritedWidget,我们希望将数据从widget树的上层传输到子widget。我们需要在传递过程中使用每个构造函数
Flutter中常用的Theme、Style、MediaQuery等都是继承的小部件,因此可以在程序中的不同位置访问它们
InheritedWidget也将在其他状态管理模式中用作传输数据的方法
InheritedWidget状态管理实现
当使用InheritedWidgets进行状态管理时,基本思想是改善状态
当子部件需要共享状态时,状态保存在其共享父部件中
首先,定义InheritedWidget的一个子类,它包含状态数据
重写两种方法:
为子级提供一个静态方法以获取自身((BuildContext)的命名约定)
确定是否已进行数据更新
类CounterStateContainer扩展InheritedWidget{
最终CounterModel数据;
计数器状态容器({
按键,
@必需的Widget子项,
@需要此数据,
}):super(键:键,子:子);
@超驰,超越
bool updateShouldNotify(CounterStateContainer旧Widget){
返回data.counter。值!=oldWidget.data.counter.value;
}
(BuildContext上下文)的静态CounterModel{
返回上下文
.dependOnInheritedWidgetOfExactType<CounterStateContainer>()
数据
}
}
然后使用CounterStateContainer将其放在上层,包括数据和所有与状态相关的小部件
无论子控件位于哪个层,都可以轻松获取状态数据
文本(

“${CounterStateContainer.of(contex