- StatefulWidget
- 按状态划分
- StatelessWidget
- StatefulWidget
- 按照作用域划分
- 组件内私有状态
- 实现跨组件状态管理
- 全局状态
- 状态组件的组成
- DataTable
- InheritedWidget
- 生命周期
- 无状态组件
- 有状态组件
- initState()
- didChangeDependencies()
- build()
- setState()
- didUpdateWidget()
- deactivate()
- dipose()
- Provider
- 优点
- 使用
StatefulWidget
按状态划分
StatelessWidget
StatefulWidget
按照作用域划分
组件内私有状态
StatefulWidget
实现跨组件状态管理
InheritedWidget、Provider
只对自己的子组件负责跨组件状态管理
全局状态
Redux、fish-redux、mobx、Scoped Model、BLoC、RxDart…
状态组件的组成
- StatefulWidget
flutter中,组件自身的数据不可变@immutable
- State
将变化的状态存入State中维护
DataTable
- columns 声明表头列表
- DataColumn 表头单元格
- rows 声明数据列表
- DataRow 一行数据
- cells 声明单元格数组
- DataCell 数据单元格
- cells 声明单元格数组
- DataRow 一行数据
InheritedWidget
提供沿树向下,共享数据
的功能
- 一般作为父类使用,子组件(继承InheritedWidget)可以获取父组件的数据
- 依赖构造函数传递数据的方式不能满足也无需求,逐层传递数据带来过高的成本和劣势
生命周期
无状态组件
只有build()
有状态组件
initState()
组件对象插入到元素树中时调用,程序运行中仅调用一次
didChangeDependencies()
当前状态对象的依赖改变时调用
build()
组件渲染时调用
setState()
组件对象的内部状态变更时调用
didUpdateWidget()
组件配置更新时调用
deactivate()
组件对象在元素树中 暂时 移除时调用
dipose()
组件对象在元素树中 永远 移除时调用
触发热更新时,调用 didUpdateWidget() -> dirty -> build()
Provider
是对 InheritedWidget 的封装。
- 工作流主要分三个模块
- 数据模型(changeNotifier) 被观察者
- Provider(changeNotifierProvider) 观察者
- Producer 生产者、Listener(Consumer) 消费者
Provider = provide + scoped_model
- 监听调用
Provider.of<T>(context) // 或 context.watch<T>(context)
- 只能用来[StatelessWidget.build] 和 [State.build] 中使用
- 监听只发生变化时,会 重建组件(更新组件刷新UI)
- 非监听调用
Provider.of<T>(context, listen: false) // 或 context.read<T>(context)
- 只能在除了[StatelessWidget.build] 或 [State.build] 之外使用
- 监听只发生变化时,不会 重建组件(不更新组件不刷新UI)
优点
- 简化资源的分配与处置
- 数据懒加载
数据模型
使用
- 安装Provider
- 创建数据模型(T extends ChangeNotifier)
- 创建Provider(注册数据模型)
- Provider() // 不会被要求随着变动而变动
- ChangeNotifierProvider() // 随着某些数据改变,被通知更新
更常用
- 获取数据模型并更新UI
- 通过上下文 buildContext
- 通过静态方法(Provider.of(context))
混入??????