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

Flutter集成Stripe支付调用Navigator.pop报查找已停用组件祖先错误如何解决

问题原因

Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe.
E/flutter ( 2773): At this point the state of the widget's element tree is no longer stable.

这个报错的核心是你在异步回调中使用了已经失效的BuildContext:

  • StripeService.payViaExistingCard是异步操作,耗时可能从几百毫秒到几秒不等,等待过程中如果用户手动点击返回键退出了当前页面,当前页面的State会被销毁,对应的context也随之失效
  • 后续你在SnackBar.closed的回调中再用这个失效的context调用Navigator.pop(context),Flutter无法通过失效的context找到组件树中的Navigator实例,就抛出了上述错误。

解决方法

按以下步骤修改即可:

  1. 所有异步回调中使用context前,先判断State的mounted属性是否为true,确认当前页面还未被销毁
  2. 提前获取NavigatorState和ScaffoldMessengerState的引用,避免多次通过context查找
  3. 优先使用State自身的context,而非ListBuilder中传进来的局部context,降低context失效的概率

修改后代码参考

首先修改payViaExistingCard方法:

// 不需要再传入context,直接用State自带的context即可
Future<StripeTransactionResponse> payViaExistingCard(card, amount) async {
  // 提前获取状态实例,不要在异步回调中再通过context查找
  final messenger = ScaffoldMessenger.of(context);
  final navigator = Navigator.of(context);
  await EasyLoading.show(status: "Please wait....");
  var expiryArr = card['expiryDate'].split('/');
  CreditCard stripeCard = CreditCard(
    number: card['cardNumber'],
    expMonth: int.parse(expiryArr[0]),
    expYear: int.parse(expiryArr[1]),
  );
  var response = await StripeService.payViaExistingCard(
      amount: '${amount}00', currency: 'USD', card: stripeCard);
  await EasyLoading.dismiss();
  // 先判断页面是否还存活,已销毁就直接返回
  if (!mounted) return response;
  messenger.showSnackBar(
      SnackBar(
        content: Text(response.message),
        duration: Duration(milliseconds: response.success == true ? 1200 : 3000),
      )
  ).closed.then((_) {
    // 回调中再次判断页面是否存活
    if (mounted) {
      navigator.pop();
    }
  });

  return response;
}

再修改点击调用的逻辑:

onTap: () {
  payViaExistingCard(card, orderProvider.amount).then((response) {
    // 回调前先判断页面是否存活
    if (!mounted) return;
    if(response.success==true){
      orderProvider.paymentStatus(response.success);
    }
  });
},

修改后所有涉及context的操作都加了存活判断,只要页面已经销毁就不会再执行后续操作,即可彻底解决该报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 18:45:05