查找停用的小部件的祖先是不安全的。 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?因为,尽管 contextdispose 中不再有效,但 contextinitState 中仍无效,因为小部件尚未插入到小部件树中.