Flutter 中 mounted 的正确使用方法详解
视频
前言
mounted
属性是 Flutter 中 State 类的重要组成部分,用于检查 StatefulWidget 是否在组件树中。正确使用 mounted
可以避免在已移除的组件上调用 setState()
,防止崩溃。本文将详细介绍 mounted
的定义、使用场景、生命周期以及最佳实践,帮助开发者在异步操作、动画回调和定时器中安全使用,提升代码健壮性。
参考
- https://docs.flutter.dev/release/breaking-changes/mouse-tracker-no-longer-attaches-annotations
- https://docs.flutter.dev/ui#responding-to-widget-lifecycle-events
什么是“mounted”属性?
“mounted”属性是 Flutter 中 State 类的一个布尔标志,用于指示 StatefulWidget 当前是否位于 widget 树中。当 State 对象被永久地从树中移除时,该属性变为 false。
为什么“mounted”很重要?
当一个组件从组件树中被移除后,尝试在其上调用 setState() 会导致异常。“mounted” 检查可以防止此类崩溃,确保我们仅在处于活动状态的组件上更新状态。
常见使用场景
1. 异步操作
Future<void> fetchData() async {
final response = await apiCall();
if (mounted) {
setState(() {
data = response;
});
}
}
2. 动画回调
controller.addStatusListener((status) {
if (mounted) {
setState(() {
// 根据动画状态更新状态
});
}
});
3. 定时器操作
Timer.periodic(Duration(seconds: 1), (timer) {
if (!mounted) {
timer.cancel();
return;
}
setState(() {
counter++;
});
});
生命周期上下文
- “mounted” 在 State.initState() 期间变为 true
- 在 State.didUpdateWidget() 和 State.setState() 期间始终保持为 true
- 在 State.dispose() 期间设置为 false
最佳实践
- 在异步操作中,调用 setState() 前务必检查 mounted 状态
- 在 dispose() 方法中取消订阅
- 在异步回调中使用 mounted 检查来进行清理
- 在复杂场景中考虑实现自动释放模式
常见陷阱
- 忘记在延迟操作中检查 mounted
- 不先检查 mounted 就依赖 context
- 未处理多个异步操作中的竞争条件
高级模式
class SafeState<T extends StatefulWidget> extends State<T> {
void safeSetState(VoidCallback fn) {
if (mounted) setState(fn);
}
}
性能考虑
mounted 检查非常轻量,因此在处理异步代码时可以放心大胆地使用。
总结要点
- mounted 属性用于检查 widget 是否在树中
- 防止在已移除的组件上调用 setState()
- 常见使用场景包括异步操作、动画回调和定时器操作
- 最佳实践包括检查 mounted 状态、取消订阅和处理异步回调
- 避免常见陷阱如忘记检查 mounted 和未处理竞争条件
- 高级模式可以通过创建 SafeState 类来封装安全的 setState 调用
- mounted 检查对性能影响微乎其微
感谢阅读本文
如果有什么建议,请在评论中让我知道。我很乐意改进。
猫哥 APP
flutter 学习路径
- Flutter 优秀插件推荐
- Flutter 基础篇1 - Dart 语言学习
- Flutter 基础篇2 - 快速上手
- Flutter 实战1 - Getx Woo 电商APP
- Flutter 实战2 - 上架指南 Apple Store、Google Play
- Flutter 基础篇3 - 仿微信朋友圈
- Flutter 实战3 - 腾讯即时通讯 第一篇
- Flutter 实战4 - 腾讯即时通讯 第二篇
© 猫哥 ducafecat.com
end