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

Flutter/Dart OTP登录应用Provider上下文异常求助

解决Provider报错:"Tried to listen to a value exposed with provider, from outside of the widget tree."

这个报错的核心原因是调用Provider.of<AuthProvider>(context, listen: false)时,传入的context不在当前Widget树中,或者Widget已被销毁。以下是针对性解决方法:

1. 调整调用时机,避免Widget未挂载时执行

如果sendPhoneNumber是在initState里直接调用的,此时Widget还未完全加入Widget树,会触发报错。可以通过WidgetsBinding.instance.addPostFrameCallback延迟到Widget挂载完成后执行:

@override
void initState() {
  super.initState();
  // 延迟到Widget渲染完成后调用
  WidgetsBinding.instance.addPostFrameCallback((_) {
    sendPhoneNumber();
  });
}

2. 调用前检查Widget挂载状态

如果sendPhoneNumber是在异步回调(比如网络请求完成、弹窗关闭后)调用,可能此时Widget已销毁,context失效。调用前先通过mounted属性判断:

void sendPhoneNumber() {
  // 先判断Widget是否还处于挂载状态
  if (!mounted) return;
  
  final ap = Provider.of<AuthProvider>(context, listen: false);
  String phoneNumber = phoneController.text.trim();
  // 修复字符串拼接语法错误:用${}而非{}
  ap.signInWithPhone(context, "+${selectedCountry.phoneCode}$phoneNumber");
}

3. 用Consumer/Selector直接获取Provider实例

如果是在Widget树的交互回调(比如按钮点击)中调用,推荐用Consumer包裹,直接获取Provider实例,避免手动处理context的问题:

// 替换按钮部分代码
Consumer<AuthProvider>(
  builder: (context, authProvider, child) {
    return ElevatedButton(
      onPressed: () {
        String phoneNumber = phoneController.text.trim();
        authProvider.signInWithPhone(context, "+${selectedCountry.phoneCode}$phoneNumber");
      },
      child: const Text('发送验证码'),
    );
  },
)

额外提示

你的代码存在字符串拼接语法错误:"+{selectedCountry.phoneCode}"应改为"+${selectedCountry.phoneCode}",否则会把{selectedCountry.phoneCode}作为纯字符串拼入,导致手机号格式错误。

内容的提问来源于stack exchange,提问作者Daniel loaiza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 09:30:59