如何修复Flutter控制器dispose后调用的‘Consider checking `mounted`.’错误?
问题描述
我已经查阅了Riverpod仓库中编号为496的Issue,尝试了其中所有用户提供的解决方案后仍无法修复错误。以下是我的代码:
调用代码:
await controller.submit( … );
控制器方法实现:
Future<void> createBroadcast(…) async { state = state.copyWith(value: const AsyncValue.loading()); final value = await AsyncValue.guard(() async { … return await …; }); state = state.copyWith(value: value); }
错误日志:
I/flutter ( 1242): Bad state: Tried to use CreateBroadcastScreenController after
disposewas called.
I/flutter ( 1242):
I/flutter ( 1242): Consider checkingmounted.
I/flutter ( 1242): …
请问该如何修复这个错误?
修复方案
这个错误的核心是控制器已被销毁(dispose),但异步操作完成后仍尝试更新状态。以下是几种可行的修复方式:
1. 新增mounted状态检查(最直接)
在更新状态的关键节点,先判断控制器是否还处于挂载状态:
Future<void> createBroadcast(…) async { // 初始检查,避免已销毁时执行后续逻辑 if (!mounted) return; state = state.copyWith(value: const AsyncValue.loading()); final value = await AsyncValue.guard(() async { … return await …; }); // 异步操作完成后再次检查,防止等待期间控制器被销毁 if (!mounted) return; state = state.copyWith(value: value); }
2. 给异步操作添加取消机制(更严谨)
如果你的异步操作支持取消(比如网络请求),可以在控制器销毁时终止操作,避免无效的状态更新:
import 'package:dio/dio.dart'; class CreateBroadcastScreenController extends StateNotifier<...> { final CancelToken _cancelToken = CancelToken(); Future<void> createBroadcast(…) async { if (!mounted) return; state = state.copyWith(value: const AsyncValue.loading()); try { // 传入取消令牌 final result = await yourApiCall(cancelToken: _cancelToken); if (!mounted) return; state = state.copyWith(value: AsyncValue.data(result)); } catch (e) { // 忽略取消操作引发的错误 if (e is DioException && e.type == DioExceptionType.cancel) return; if (!mounted) return; state = state.copyWith(value: AsyncValue.error(e)); } } @override void dispose() { // 销毁时取消异步操作 _cancelToken.cancel('控制器已销毁'); super.dispose(); } }
3. 规范控制器方法的调用时机
检查触发controller.submit()的场景,确保只有在页面/组件处于活跃状态时才调用:
// 例如在StatefulWidget的组件中 ElevatedButton( onPressed: mounted ? () => controller.submit(…) : null, child: const Text('提交'), )
内容的提问来源于stack exchange,提问作者My Car
相关产品推荐
相关产品推荐

