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

Flutter实现showSnackBar遇报错:Don't use 'BuildContext's across async gaps

解决Flutter中"Don't use 'BuildContext's across async gaps"错误

这个报错的核心原因是:你在异步操作(比如await http.post)完成后直接使用了BuildContext。异步等待的过程中,当前Widget可能已经被销毁(比如用户返回上一页),此时context已经失效,继续调用会引发异常。

最简单的修复方案:添加mounted检查

在调用ScaffoldMessenger.of(context)之前,先判断当前Widget是否还处于挂载状态(mounted为true),确保context有效后再执行弹窗逻辑。

修改后的代码如下:

//Post reply
replyThread() async{
  setState(() { _isSubmitted = true; });
  try{
      var res = await http.post(
      Uri.parse(API.quickThreadReplyURL),
        body: {
            'post_id': _postid.toString(),
            'userID': userID.toString(),
            'sessionData': sessionData.toString(),
            'content': contentController.text,
        },
      );
      if(res.statusCode==200){
          //Clear textfield
          contentController.text = '';
          final resBody = jsonDecode(res.body);
          bool success = resBody['success'];
          if(success){
              List thread = resBody['threadList'] as List;
              setState(() {
                threadReplies = thread + threadReplies;
                _isSubmitted = false;
              });
              //Show toaster
              if(mounted){ // 新增mounted检查
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(
                    backgroundColor: Color.fromARGB(255, 139, 247, 92),
                    content: 
                    Text(
                      "New thread reply successfully posted",
                      style: TextStyle(color: Colors.black),
                    ),
                  )
                );
              }
          }
          else{
            setState(() { _isSubmitted = false; });
            //Show toaster
            if(mounted){ // 新增mounted检查
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(
                  backgroundColor: Color.fromARGB(255, 240, 96, 96),
                  content: 
                  Text(
                    "Oops! Something went wrong. Reply not posted",
                    style: TextStyle(color: Color.fromRGBO(255, 255, 255, 1)),
                  ),
                )
              );
            }
        }
      }
  }
  catch(e){
    print(e.toString());
    // 也可以在这里添加mounted检查后显示错误弹窗
    if(mounted){
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          backgroundColor: Colors.red,
          content: Text("Network error occurred"),
        )
      );
    }
  }
}

另一种方案:使用GlobalKey

如果不想依赖Widget的context,可以提前定义一个GlobalKey<ScaffoldMessengerState>,通过它来调用SnackBar:

  1. 在Widget类中定义全局Key:
final GlobalKey<ScaffoldMessengerState> _scaffoldKey = GlobalKey<ScaffoldMessengerState>();
  1. 在Scaffold中绑定这个Key:
Scaffold(
  key: _scaffoldKey,
  // ...其他代码
)
  1. 调用SnackBar时直接用Key:
_scaffoldKey.currentState?.showSnackBar(/* SnackBar内容 */);

这种方式不需要检查mounted,因为currentState会自动判断是否有效。

内容的提问来源于stack exchange,提问作者Cliff Odebala Clarke

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:07:45