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

Flutter调用_onParameterValueChange报错,需在didChangeDependencies中调用指定方法

Flutter 解决“查找已停用Widget的祖先不安全”错误

问题场景

启动页为StatelessWidget,通过ChangeNotifierProvider向MYpage传递信息,MYpage的initState代码如下:

@override
void initState() {
super.initState();
if (mounted) {
setState(() {
parameterValueNotifier = widget.parameterValueNotifier;
parameterValueNotifier.onValueChanged = _onParameterValueChange;
parameterValue = parameterValueNotifier.value;
});
}
} 
void _onParameterValueChange(String newValue) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => AnotherPage(parameterValue: newValue),
),
);
}

错误日志

I/flutter (25975): Looking up a deactivated widget's ancestor is unsafe.
I/flutter (25975): At this point the state of the widget's element tree is no longer stable.
I/flutter (25975): To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.
I/flutter (25975): #0 Element._debugCheckStateIsActiveForAncestorLookup.<anonymous closure> (package:flutter/src/widgets/framework.dart:4334:9)

解决方案

核心原因

当MYpage已从组件树中移除(deactivated)时,_onParameterValueChange被调用,此时通过当前context获取Navigator会触发错误——因为该context对应的组件状态已失效,无法安全查找祖先组件。

具体修复步骤

  1. 提前保存Navigator引用
    在didChangeDependencies方法中获取并保存NavigatorState的引用,确保后续使用时的安全性:
late NavigatorState _navigator;

@override
void didChangeDependencies() {
  super.didChangeDependencies();
  _navigator = Navigator.of(context);
}
  1. 替换回调中的导航逻辑
    将_onParameterValueChange里的Navigator.of(context)替换为提前保存的_navigator:
void _onParameterValueChange(String newValue) {
  _navigator.push(
    MaterialPageRoute(
      builder: (_) => AnotherPage(parameterValue: newValue),
    ),
  );
}
  1. 清理监听避免内存泄漏
    在dispose方法中清空对parameterValueNotifier的回调引用,防止Notifier持有已销毁的State实例:
@override
void dispose() {
  parameterValueNotifier.onValueChanged = null;
  super.dispose();
}
  1. 简化initState逻辑
    initState中的setState是多余的,直接赋值即可(组件初始化阶段无需触发重建):
@override
void initState() {
  super.initState();
  parameterValueNotifier = widget.parameterValueNotifier;
  parameterValueNotifier.onValueChanged = _onParameterValueChange;
  parameterValue = parameterValueNotifier.value;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 23:25:29