20.3.23 一
状态管理是声明式编程里非常重要的一个概念
命令式编程 -> 声明式编程
UI = f( state )
数据、成员变量 -> 状态
build方法展示 -> UI界面
setState()
1.2 不同状态管理分类
1.2.1 短时状态 Ephemeral state
某些状态只需要在自己的Widget中使用
计数器counter
PageView
动画记录当前的进度
BottomNavigationBar中记录当前被选中的tab
缺点: Widget树中其他Widget不能访问
1.2.2 应用状态App state
开发中也有非常多的状态列甩开多个部分进行共享
-
用户一个个性化选项
根据选择过滤一部分东西 -
用户的登录状态信息
登录信息, token, 用户信息, 多个界面都进行展示 -
电商应用的购物车
-
新闻应用的一度消息或者未读消息
对状态进行统一的管理和应用
1.2.3如何选择不同的管理方式
并没有一个明确的规则, 可能会升级
怎么简单怎么来
共享状态管理
2.1 InheritedWidget
counter共享管理
官方提供两种方式
- InheritedWidget
- Provider 官方更推崇
抽象方法必须实现
JHCounterWidget
updateShouldNotify 方法
封装一个静态方法获取对象
特点
继承自 InheritedWidget
必须实现update...fy方法
定义一个共享状态
通过静态方法拿到对象
共享一个counter
找到共同的祖先, 祖先包裹一个Widget
传进来context
树结构往上去找, 找到最近的对象
静态方法返回的null(有错误!) -> 返回 context.dependOnInheritedWidgetOfExactType
作用: 沿着Element树, 去找到最近的JHCounterElement
从Element中取出Widget对象
Widget里的属性都是不能改变的 -> 重新创建
返回false数据改了, 不执行didChangeDependence方法
返回true, 执行didChangeDependence方法
如何选? 看第一次传入的counter和第二次传入的有没有改变
- 共享的数据
- 自定义构造方法
- 获取组件最近的当前InheritedWidget
- 要不要回调State中的didChangeDependencies
如何找的? 点到dependOnInheritedWidgetOfExact
结构理清楚, 写一下代码
并不是很复杂, 第一次用可能觉得麻烦点
2.2 Provider
官方已开始推荐的是Provide
相当于React中的Redux
官方提供的一个第三方的东西
添加依赖
Provider怎么用?
可能共享的数据有很多
一般在最顶层, MyApp
打开箭头函数
runApp(
ChangeNotifierProvider {
child: MyApp(),
}
);
使用步骤
- 创建自己需要共享的数据
- 在应用程序的顶层ChangeNotifierProvider
- 在其他位置使用共享的数据
- Provider.of
- Consumer
- Selector
创建一个文件夹 viewmodel或store(商店, 仓库)
MVVM架构
在这个文件夹里创建需要共享的数据
快捷键: cmd + N, 快速生成getter、setter、toString、Constructor
第三步
of 泛型方法
底层依赖InheritedWidget, 做了很多优化
Provider.of更简洁,
当Provider中的数据发生改变时, 所在的Widget整个build都会被重新执行
开发中更多的使用Consumer(相对推荐)
当Provider中的数据发生改变是, 只会重新执行传入的builder
没有必要重新构建的进行优化
-
child: Icon优化
Consumer还有一个参数 child
Icon移到这里来, 点击加号, Icon就不会重新构建了
builder中的参数child就是Consumer的参数child -
FloatingActionButton也不需要重新构建
Consumer -> Selector
Selector有2个作用
- 对原有的JHCounterViewModel进行一个转换
- shouldRebuild要不要重新构建, 返回false
shouldRebuild: (prev, next) => false,
2.2.4 MultiProvider
方式一: 多个Provider之间嵌套
弊端, 不方便维护, 扩展性差
方式二: MultiProvider
搞一个initialize_providers.dart文件
统一维护
Consumer2
...
Consumer5
Consumer6
传多个共享数据
网络请求放在Provider里面
拿到请求后, 通知一下
类似于观察者模式
第一次写的时候会不习惯,
先看源码, 后看老师的代码
网友评论