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

Flutter Web切换页面点击表单报FocusNode was used after being disposed错误求助

问题原因

这个错误是FocusNode被销毁后仍被焦点管理器调用导致的,触发场景和你的页面切换逻辑直接相关:

  1. 你在BloodDonationPage中通过布尔变量条件渲染两个子页面,当切换到「List Donors」页面时,BloodDonorDetailPage(添加捐赠者页面)会被直接从Widget树中移除,页面实例、对应的State以及内部FormBuilderTextField自动创建的FocusNode都会被执行dispose销毁。
  2. 你给姓名输入框设置了autofocus: true,首次进入添加页面时焦点默认落在该输入框上,切换页面销毁旧实例时,Flutter焦点管理器仍持有旧的FocusNode引用,切回页面点击输入框时,框架尝试调用已经销毁的FocusNode处理焦点逻辑,就抛出了这个错误。
解决方案

提供两种可选修复方案:

方案1:缓存页面实例(推荐)

使用IndexedStack替代条件渲染,切换页面时仅隐藏页面不销毁实例,避免FocusNode被频繁销毁重建:

  1. 在_BloodDonationPageState中新增索引变量:
int _currentIndex = 0;
  1. 修改两个按钮的点击逻辑:
    点击「Add Donor」时执行setState(() => _currentIndex = 0);,点击「List Donors」时执行setState(() => _currentIndex = 1);
  2. 替换原有条件渲染的页面代码:
Flexible(
  child: IndexedStack(
    index: _currentIndex,
    children: const [
      BloodDonorDetailPage(),
      ListBloodDonorPage(),
    ],
  ),
)

方案2:销毁页面前手动清理焦点

如果需要每次进入添加页面都重建实例,可以在页面销毁前手动释放焦点,切断旧FocusNode的引用:
在_BloodDonorDetailPageState中重写dispose方法:

@override
void dispose() {
  FocusManager.instance.primaryFocus?.unfocus();
  super.dispose();
}
额外优化建议

你在BloodDonorDetailPage中额外嵌套了一层Scaffold,外层BloodDonationPage已经处于路由上下文内,重复嵌套Scaffold可能导致焦点上下文混乱,建议去掉BloodDonorDetailPage中FormBuilder下的Scaffold,直接用Column作为子组件即可。

内容的提问来源于stack exchange,提问作者Santhavathi Sivakumaran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 12:57:03