ChangeNotifier变量变更时Consumer是否更新?StateNotifier场景表现如何?
关于ChangeNotifier与StateNotifier的组件更新问题
问题1:当ChangeNotifier中的另一个变量发生变更时,Consumer的model会更新吗?
- 会更新。只要ChangeNotifier调用了
notifyListeners(),所有监听它的Consumer都会触发builder重建——这个触发逻辑只和notifyListeners()的调用有关,和变更的是不是当前Consumer用到的变量完全无关。
问题2:调用setIntVal方法并执行notifyListeners()后,仅intVal变更而strVal未变更,此时Text组件会重绘吗?另外,使用StateNotifier时会出现怎样的情况?
ChangeNotifier场景
- 会重绘。因为
setIntVal中调用了notifyListeners(),不管Text依赖的strVal有没有变化,Consumer都会重新执行builder方法,Text组件会被重建。虽然最终显示内容没变,但Flutter会触发重绘流程(不过框架可能会通过优化跳过实际的像素渲染,但builder方法确实会执行)。
StateNotifier场景
- 情况会不同。
StateNotifier的更新逻辑基于状态对象的替换:只有当状态对象被全新替换(而非修改现有对象的内部属性)时,才会通知监听者。- 示例代码如下:
class DummyState { final int intVal; final String strVal; DummyState({required this.intVal, required this.strVal}); // 通过copyWith创建新状态对象,而非修改原对象属性 DummyState copyWith({int? intVal, String? strVal}) { return DummyState( intVal: intVal ?? this.intVal, strVal: strVal ?? this.strVal, ); } } class DummyManager extends StateNotifier<DummyState> { DummyManager() : super(DummyState(intVal: 0, strVal: "")); void setIntVal(int val) { state = state.copyWith(intVal: val); } } - 此时用
Consumer(或StateNotifierBuilder)监听DummyManager,调用setIntVal替换状态后,Consumer的builder会执行,但由于新状态的strVal和旧状态完全一致,Flutter的diff算法会识别出内容无变化,不会触发实际的组件重绘,只会跳过不必要的渲染步骤。
- 示例代码如下:
内容的提问来源于stack exchange,提问作者Ganessa
相关产品推荐
相关产品推荐

