为何Riverpod的ConsumerWidget可响应状态变化?两类消费者组件有何差异?
这俩组件本质是互补关系,分别对应不同的开发场景,核心是为了兼顾全局/跨组件状态管理和组件本地状态管理的需求:
什么时候必须用ConsumerStatefulWidget?
需要组件专属的本地状态时
比如文本输入框的临时输入内容、弹窗的显示/隐藏状态、仅当前组件用到的动画控制器(AnimationController),这些状态不需要共享给其他组件,用本地状态管理更高效也更合理。这时候你需要借助ConsumerStatefulWidget的State类,通过setState更新本地状态,同时还能通过ref监听Riverpod的全局状态。
举个例子:一个提交表单的页面,输入框内容用本地状态存,提交时再调用全局provider把数据发出去,这种场景用ConsumerStatefulWidget就很顺手。需要处理组件生命周期逻辑时
如果你要在组件初始化时(initState)订阅流、初始化资源,或者在组件销毁时(dispose)释放资源,ConsumerWidget作为无状态组件没有这些生命周期方法,只能用ConsumerStatefulWidget来实现。
比如做一个带动画的倒计时组件,要在initState初始化动画控制器,dispose时销毁它,同时还要从全局provider获取倒计时时长,这时候ConsumerStatefulWidget是唯一选择。局部UI更新的性能优化
当组件的部分UI更新只依赖本地状态时,用setState只会触发当前组件的局部重建,比触发全局provider的状态更新更轻量。比如一个仅控制当前组件样式的开关按钮,切换状态不需要同步到全局,用本地状态更新更高效。
什么时候用ConsumerWidget?
当组件完全依赖Riverpod管理的状态,没有自己的本地状态,也不需要处理生命周期逻辑时,ConsumerWidget的代码更简洁,比如counter示例里的计数器,只需要展示全局状态、触发全局状态变化,用ConsumerWidget就足够。
简单说,Riverpod提供这俩组件是为了让开发者能灵活组合全局状态和本地状态,不用为了用状态管理框架就放弃组件本身的本地状态能力,适配更多真实开发场景。
内容的提问来源于stack exchange,提问作者duckling

