【问题标题】:Do not use BuildContexts across async gaps不要跨异步间隙使用 BuildContexts
【发布时间】:2021-10-22 13:56:36
【问题描述】:

我注意到我的项目中有一个新的 lint 问题。

长话短说:

我需要在我的自定义类中使用 BuildContext

flutter lint 工具在与 aysnc 方法一起使用时不满意。

例子:

   MyCustomClass{

      final buildContext context;
      const MyCustomClass({required this.context});

      myAsyncMethod() async {
        await someFuture();
        # if (!mounted) return;          << has no effect even if i pass state to constructor
        Navigator.of(context).pop(); #   << example
      }
   }

【问题讨论】:

  • 出于导航的目的将上下文传递给这样的对象似乎并不明智。如果在将上下文传递给 MyCustomClass 后导航堆栈发生更改,并且您尝试使用旧上下文再次导航,则会出现错误。
  • 我同意,那么应该如何处理这种情况?
  • 使用一些状态管理,比如 BloC,当状态改变时你可以触发导航。只要您不存储上下文,而是将上下文用于导航目的而不存储实例。

标签: flutter dart flutter-dependencies flutter-state flutter-build


【解决方案1】:

只需将您的导航器或任何需要上下文的内容保存到函数开头的变量中

      myAsyncMethod() async {
        final navigator = Navigator.of(context); // 1
        await someFuture();
        navigator.pop();  // 2
      }

【讨论】:

  • 不要小心这样做! context 可能没有安装,所以这绝对不能保证解决问题,而是可能导致应用崩溃!
【解决方案2】:

不要将上下文直接存储到自定义类中,如果您不确定您的小部件是否已安装,请不要在异步之后使用上下文。

做这样的事情:

class MyCustomClass {
  const MyCustomClass();

  Future<void> myAsyncMethod(BuildContext context, VoidCallback onSuccess) async {
    await Future.delayed(const Duration(seconds: 2));
    onSuccess.call();
  }
}

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  @override
  Widget build(BuildContext context) {
    return IconButton(
      onPressed: () => const MyCustomClass().myAsyncMethod(context, () {
        if (!mounted) return;
        Navigator.of(context).pop();
      }),
      icon: const Icon(Icons.bug_report),
    );
  }
}

【讨论】:

    【解决方案3】:

    进行此更改:

    MyCustomClass{
      final buildContext context;
      const MyCustomClass({required this.context});
    
      myAsyncMethod() async {
        await someFuture();
        # if (!mounted) return;    
        Future.delayed(Duration.zero).then((_) {
          Navigator.of(context).pop();
        });
      }
    }
    

    【讨论】:

    • 不幸的是,您不能在自定义类中使用 mount 属性;(
    • 这个错误是由if (!mounted) return;检查这个变量/属性mounted引起的。它给出了错误,因为您不能在自定义类中使用 mounted
    • 我没有使用 mount 属性,因为显然你不能在自定义类中使用它。
    猜你喜欢
    • 2023-01-15
    • 2022-12-31
    • 2023-02-19
    • 2023-02-09
    • 2020-10-03
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 2019-07-23
    相关资源
    最近更新 更多