【问题标题】:Extending setState to only run if mounted将 setState 扩展为仅在已安装时运行
【发布时间】:2021-11-05 06:35:38
【问题描述】:

我正在尝试编写扩展方法以避免在未安装小部件时调用 setState 出现问题。代码如下所示:

import 'package:flutter/widgets.dart';

extension SetStateIfMounted on State {
  void setStateIfMounted(VoidCallback onMounted, [ VoidCallback onNotMounted ]) {
    if (mounted) {
      setState(onMounted);
    } else {
      LogService.logger.w('Widget not mounted. setState being ignored');
      if (onNotMounted != null)
        onNotMounted();
    }
  }
}

这是个坏主意吗?是否有某些原因我不想在调用 setState() 之前检查小部件是否已安装?

【问题讨论】:

  • 为什么不让异常从这个异步调用中爆发呢? stackoverflow.com/a/63593001/679553
  • @GazihanAlankus 你什么意思?你是在问我为什么有 else 语句?
  • 或者你是说完全忽略它?
  • 是的,我会说忽略它。这发生在小部件卸载后的异步调用中。这个异步函数无论如何都不应该继续。我认为 if(mounted) 甚至可能是有害的,因为它让功能在小部件卸载后继续工作。你可以从这个返回,但它的调用者会继续执行。异常成功地摆脱了这个异步调用。我只是忽略这些。
  • 在我的例子中,setState 是在计时器内部调用的。如果我忽略它,控制台就会被异常消息淹没。如果未安装计时器,我可以使用我制作的扩展功能来停止计时器setStateIfMounted(() => currentIndex++, () => timer.cancel());

标签: flutter widget state


【解决方案1】:

为什么不创建一个扩展 State 并覆盖 setState(...) 的抽象类。

abstract class SafeState<T extends StatefulWidget> extends State<T> {
  @override
  void setState(VoidCallback fn) {
    if (!mounted) {
      return;
    }

    super.setState(fn);
  }
}

StatefulWidget 的状态下,扩展SafeState 而不是State

【讨论】:

    猜你喜欢
    • 2017-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-21
    相关资源
    最近更新 更多