Flutter Web切换页面点击表单报FocusNode was used after being disposed错误求助
问题原因
这个错误是FocusNode被销毁后仍被焦点管理器调用导致的,触发场景和你的页面切换逻辑直接相关:
- 你在
BloodDonationPage中通过布尔变量条件渲染两个子页面,当切换到「List Donors」页面时,BloodDonorDetailPage(添加捐赠者页面)会被直接从Widget树中移除,页面实例、对应的State以及内部FormBuilderTextField自动创建的FocusNode都会被执行dispose销毁。 - 你给姓名输入框设置了
autofocus: true,首次进入添加页面时焦点默认落在该输入框上,切换页面销毁旧实例时,Flutter焦点管理器仍持有旧的FocusNode引用,切回页面点击输入框时,框架尝试调用已经销毁的FocusNode处理焦点逻辑,就抛出了这个错误。
解决方案
提供两种可选修复方案:
方案1:缓存页面实例(推荐)
使用IndexedStack替代条件渲染,切换页面时仅隐藏页面不销毁实例,避免FocusNode被频繁销毁重建:
- 在
_BloodDonationPageState中新增索引变量:
int _currentIndex = 0;
- 修改两个按钮的点击逻辑:
点击「Add Donor」时执行setState(() => _currentIndex = 0);,点击「List Donors」时执行setState(() => _currentIndex = 1); - 替换原有条件渲染的页面代码:
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
相关产品推荐
相关产品推荐

