flutter - 查找已停用小部件的祖先是不安全的。Navigator.of(context).pushAndRemoveUntil
问题描述
navigator.pushandremoveuntil 工作正常,但抛出异常:此语句从扩展 ChangeNotifier(提供程序)的类执行。
最终确定小部件树时引发了以下断言:查找已停用小部件的祖先是不安全的。
此时小部件的元素树的状态不再稳定。
要在其 dispose() 方法中安全地引用小部件的祖先,请通过在小部件的 didChangeDependencies() 方法中调用dependOnInheritedWidgetOfExactType() 来保存对祖先的引用。
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (_) {return EmailAuthVC();}), (Route<dynamic> route) => false);
解决方案
错误是什么?
正如错误所解释的,您正在尝试dependOnInheritedWidgetOfExactType
在 dispose 方法中使用。
这真正意味着context
您正在使用的 不再是小部件树的一部分(因为它的状态已被释放),因此您不能使用它来调用dependOnInheritedWidgetOfExactType
.
但是你在哪里使用dependOnInheritedWidgetOfExactType
?在Navigator.of(context)
. 如果你检查它的源代码:
static NavigatorState of(
BuildContext context, {
bool rootNavigator = false,
}) {
// Handles the case where the input context is a navigator element.
NavigatorState? navigator;
if (context is StatefulElement && context.state is NavigatorState) {
navigator = context.state as NavigatorState;
}
if (rootNavigator) {
navigator = context.findRootAncestorStateOfType<NavigatorState>() ?? navigator;
} else {
navigator = navigator ?? context.findAncestorStateOfType<NavigatorState>();
}
...
return navigator!;
}
如何解决这个问题?
您必须使用上下文来获取方法Navigator
之前的dispose
内容。如错误中所述,您应该创建对对象的引用(didChangeDependencies
例如在方法中)并在以后使用它。
这是一个具体的例子:
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
// The reference to the navigator
late NavigatorState _navigator;
@override
void didChangeDependencies() {
_navigator = Navigator.of(context);
super.didChangeDependencies();
}
@override
void dispose() {
_navigator.pushAndRemoveUntil(..., (route) => ...);
super.dispose();
}
@override
Widget build(BuildContext context) {
return ...;
}
}
为什么不使用initState
方法而不是didChangeDependencies
?因为,尽管 中context
不再有效dispose
,但由于尚未将小部件插入到小部件树中,所以context
仍然无效。initState
推荐阅读
- python - 您如何使用 Kivy GUI 访问其他类方法和函数?
- typescript - ReferenceError:未定义 WebGLRenderingContext
- python - 导入 TensorFlow 时出错 - 无法加载原生 TensorFlow 运行时
- javascript - typescript:在 typescript 项目中使用声明文件来全局公开类型
- c - 如何在 MSYS2 中建立 GMP?
- sql - 使用插入和更新模拟 SQL 合并
- spring - 在多对多中只获取 id 而不是整个对象
- java - 为什么当我打开一个新的 JFrame 时,我的组件会改变格式?
- arrays - 分配时对数组使用 typedef 是否比数组本身占用更多内存?
- python - 无法在命令提示符下使用 pip 下载 streamlit