查找停用的小部件的祖先是不安全的。 Navigator.of(上下文).pushAndRemoveUntil
Looking up a deactivated widget's ancestor is unsafe. Navigator.of(context).pushAndRemoveUntil
navigator.pushandremoveuntil 工作正常但抛出异常:
此语句从扩展 ChangeNotifier(提供者)的 class 执行。
完成小部件树时抛出了以下断言:
查找已停用的小部件的祖先是不安全的。
此时widget的元素树状态不再稳定
要在其 dispose() 方法中安全地引用小部件的祖先,请通过在小部件的 didChangeDependencies() 方法中调用 dependOnInheritedWidgetOfExactType() 来保存对祖先的引用。
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (_) {return EmailAuthVC();}), (Route<dynamic> route) => false);
错误是什么?
如错误所述,您正在尝试在处置方法中使用 dependOnInheritedWidgetOfExactType
。
这实际上意味着您正在使用的 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!;
}
如何解决?
在 dispose
方法之前,您必须使用上下文来获取Navigator
。如错误中所述,您应该创建对该对象的引用(例如在 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
中仍无效,因为小部件尚未插入到小部件树中.
navigator.pushandremoveuntil 工作正常但抛出异常: 此语句从扩展 ChangeNotifier(提供者)的 class 执行。
完成小部件树时抛出了以下断言: 查找已停用的小部件的祖先是不安全的。
此时widget的元素树状态不再稳定
要在其 dispose() 方法中安全地引用小部件的祖先,请通过在小部件的 didChangeDependencies() 方法中调用 dependOnInheritedWidgetOfExactType() 来保存对祖先的引用。
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (_) {return EmailAuthVC();}), (Route<dynamic> route) => false);
错误是什么?
如错误所述,您正在尝试在处置方法中使用 dependOnInheritedWidgetOfExactType
。
这实际上意味着您正在使用的 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!;
}
如何解决?
在 dispose
方法之前,您必须使用上下文来获取Navigator
。如错误中所述,您应该创建对该对象的引用(例如在 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
中仍无效,因为小部件尚未插入到小部件树中.