You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

销毁Widget时更新StateProvider报错,如何正确实现状态置空?

解决Dispose中更新StateProvider的异常问题

问题原因

在dispose()方法中调用ref.read()会触发对Provider祖先节点的查找,但此时Widget已经被停用,Element树状态不稳定,导致抛出"Looking up a deactivated widget's ancestor is unsafe"的断言错误。

正确解决方案

方案1:使用ref.onDispose注册清理回调(推荐)

在Widget的initState()中注册销毁时的回调,该回调会在Widget即将销毁但Element树仍稳定的阶段执行:

@override
void initState() {
  super.initState();
  // 注册Widget销毁时的状态重置逻辑
  ref.onDispose(() {
    ref.read(fsdMapStateProvider.notifier).state = null;
  });
}

方案2:提前保存Notifier引用

在didChangeDependencies()中提前获取Notifier的引用并存储,在dispose()中直接使用该引用更新状态:

late final FsdMapStateNotifier _mapStateNotifier;

@override
void didChangeDependencies() {
  super.didChangeDependencies();
  // 在依赖可用时保存Notifier引用
  _mapStateNotifier = ref.read(fsdMapStateProvider.notifier);
}

@override
void dispose() {
  // 使用提前保存的引用重置状态
  _mapStateNotifier.state = null;
  super.dispose();
}

注意事项

  • 避免在dispose()中直接调用ref.read()或ref.watch(),此时Widget的上下文关系已失效。
  • 方案1更符合Riverpod的设计理念,无需额外维护成员变量,推荐优先使用。

内容的提问来源于stack exchange,提问作者Richard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:30:59