20210703setState()与onChange的区别(3) - ziyouzy/2021blog GitHub Wiki

需要把setState()所属的原生业务逻辑与ChangeNotifier所属的原生业务逻辑对比起来探讨
他们其实都是负责状态(变量与数据)管理的,区别在于:
如果没有特殊情况,ChangeNotifier应用来负责全局状态管理;setState应该负责局部状态管理

他们两个所谓的“全局”与“局部”间的业务逻辑分界线是在于“Widget外与内”换句话说,setState是widget内部的功能,只能实现这个widget内部的数据交换
但也能实现“跨Widget的数据交换”,而这种跨越都是局限于某个父Widget以及这个父Widget内部的子Widget的

而ChangeNotifier则不同,他可以独立于Widget在逻辑顶层独立运行,是实现类似于tcpSocket与ui之间状态管理的必备工具
换句话说,ChangeNotifier将用于实现程序内功能模块的(状态管理)数据交互,如UI模块与TcpSock模块

最后来探讨下ChangeNotifier所特有的广播/订阅机制,不过需要反过来看这个问题,先看一段原生代码:

abstract class State<T extends StatefulWidget> with Diagnosticable {
    //setState()方法存在于此
}

因此也就是说被StatefulWidget所包裹的那些“零件Widget”(如CheckBox)
如果他们的父类不是StatefulWidget或State那么就无法在这个零件Widget里调用setState()了,
因为根本没有这个方法,如原生代码中:

class Text extends StatelessWidget {}
class Icon extends StatelessWidget {}
甚至是class FloatingActionButton extends StatelessWidget {}

显而易见的,你懂的
换句话说
UI框架大部分时候是一个StatefulWidget包裹着多个StatelessWidget
就像是一个大哥带着好几个小弟玩,如果没有大哥小弟们都不知道平时去干什么

小弟没办法自己刷新自己,但是大哥却可以刷新自己以及属于他的小弟
另一个侧面讲,ChangeNotifier是“手机大哥大”,也可以用来实现大哥与大哥之间的通信,从而让大哥根据具体情况来决定接下来需要做什么(比如刷新自己和众小弟)
有一点点像之前的pr

**但是还有个问题,大哥可以去刷新某一个小弟吗?答案是不行的:

Widget build(BuildContext context) {
    //小弟们
}

大哥刷新的是build内部所包含的小弟们,换句话说,“大哥”只能刷新“大哥自己”

于是乎,一个大哥里不能包含太多小弟,要不然每次刷新就太浪费资源了
比如即将去复刻的仪表盘
正确的设计模式是每个仪表盘都会是一个大哥,而不能去让一个“无形的大哥”去包裹多个“有形的小弟”
至此一切都总结好了,如有问题实操过程中在继续学习吧