文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

关于 Flutter 中 Mounted 属性您需要了解的一切

2024-11-29 19:14

关注

什么是已 mounted 属性?

Mounted 属性是 Flutter 框架在 State 类中提供的布尔标志。它指示状态对象当前是否在小部件树中。

创建 State 对象之后、调用 initState 之前,框架通过将 State 对象与 BuildContext 关联来“mounted”该对象。State 对象保持挂载状态,直到框架调用 dispose,之后框架将不再要求 State 对象再次构建。换句话说,当一个 widget 从 widget 树中删除时,其关联的状态对象也被删除,并且 mounted 属性被设置为 false。

mounted 属性的目的是什么?

Mounted 属性的主要目的是帮助您管理状态并避免与不再属于小部件树一部分的小部件交互时可能发生的潜在错误。具体来说,mounted 在涉及异步操作或延迟操作的场景中很有用。

何时使用 Mounted 属性?

我认为应该把第一名让给异步操作。

当执行异步操作(例如网络请求、数据库查询)时,一旦操作完成,状态对象可能会被更新。但是,如果在操作完成之前将小部件从小部件树中删除,则尝试更新状态可能会导致运行时错误。在这种情况下,mounted 属性允许您在进行任何更新之前检查状态对象是否仍然处于活动状态。

String _data = '';
bool _isFetching = false;

@override
 void initState() {
   super.initState();
   _fetchData();
 }

void _fetchData() async {
  // assuming that _isFetching is a boolean that tracks the loading state
  setState(() {
    _isFetching = true;
  });

  try {
    final data = await fetchDataFromServer();
    if (mounted) {
      setState(() {
        _data = data;
        _isFetching = false;
      });
    }
  } catch (error) {
    if (mounted) {
      setState(() {
        _isFetching = false;
        _error = error;
      });
    }
  }
}

异步操作完成后,我们在调用 setState 之前检查 Mounted 属性。这确保了小部件仍然是小部件树的一部分。

为什么这很重要?同样,如果小部件已从树中删除(例如,由于导航离开页面或小部件被处置),调用 setState 将导致运行时错误。在这里,我们的辅助 Mounted 属性通过确认小部件仍然处于活动状态并且可以安全更新来防止这种情况发生。

让我们进入下一个环节:计时器和延迟操作、动画。

当使用计时器、延迟操作或动画时,小部件可能会在计时器或操作完成之前被丢弃。如果在调用 setState 之前检查 mounted 属性,就能确保只有在部件仍处于活动状态时才进行更新。

void _startTimer() {
  Timer.periodic(Duration(seconds: 1), (timer) {
    if (mounted) {
      setState(() {
        _counter++;
      });
    }
  });
}

在 dispose 方法中,清理任何资源或取消正在进行的操作至关重要。由于当小部件即将从小部件树中删除时会调用 dispose,因此最好在执行可能依赖于小部件状态的操作之前检查 mounted 属性是一个很好的做法。

@override
void dispose() {
  _timer?.cancel();
  super.dispose();
}

另一个是:Navigator。

如果要执行可能被导航中断的异步操作(如使用 Navigator.push 或 Navigator.pop),请确保在更新状态前挂载部件。

Future _navigateAndFetchData() async {
  Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => AnotherPage()),
  );

  final result = await someAsyncOperation();
  if (mounted) {
    setState(() {
      _data = result;
    });
  }
}

我想讨论的最后一个是:具有异步初始化的有状态小部件。

对于在 initState 中执行异步操作的有状态小部件,最好使用 Mounted 属性来确保仅在小部件处于活动状态时才发生更新。

@override
void initState() {
  super.initState();
  _initializeAsync();
}

Future _initializeAsync() async {
  final data = await fetchData();
  if (mounted) {
    setState(() {
      _data = data;
    });
  }
}

好吧好吧,这是最后一篇:长时间运行的操作。

对于长时间运行的任务,例如文件 I/O 或计算,您可以在调用 setState 之前使用 Mounted 属性来确保 UI 更新是安全的。

Future performLongRunningTask() async {
  await longRunningTask();
  if (mounted) {
    setState(() {
      _taskCompleted = true;
    });
  }
}

为什么要使用 Mounted 属性?

如果总结我们的讨论,我们得到的是:

什么时候 mounted 属性可能不是必需的?

同步操作:用于不涉及异步任务或后台操作的纯同步操作。然而,确保适当的资源管理并避免在小部件处置期间更新状态仍然很重要。

简单小部件:适用于不涉及任何异步逻辑、后台任务或复杂生命周期管理的简单小部件。

在 Flutter 3.7 中使用 context.mounted

在 Flutter 3.7 之前,无法检查 Flutter 中是否安装了 StatelessWidget。这只能在 State/Stateful 小部件上实现。

但从Flutter 3.7开始,BuildContext 本身就有一个 mounted 属性。

这使得检查是否安装了任何小部件变得很容易,并且您可以从任何地方检查它,无论它来自 StatefulWidget State 还是来自 Stateless widget,就像这样:

// inside any widget
@override
Widget build(BuildContext context) {
  return ElevatedButton(
    child: const Text('Submit'),
    onPressed: () async {
      await doSomeAsyncWork(); // a method that returns a Future
      if (context.mounted) {
        Navigator.of(context).pop();
      }
    },
  );
}

我在 StackOverflow 上看到很多关于无论如何都要在任何地方使用 mounted 属性的必要性的问题。请记住,使用 mounted 属性不是强制性的,但这是一个很好的做法。在特殊情况下使用的良好实践。

原文:https://medium.com/@wartelski/everything-you-need-to-know-about-the-mounted-property-in-flutter-b603fdb51cb4

来源:独立开发者张张内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯