不要跨异步间隙使用 BuildContexts
Do not use BuildContexts across async gaps
我注意到我的项目中有一个新的 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{
final buildContext context;
const MyCustomClass({required this.context});
myAsyncMethod() async {
await someFuture();
# if (!mounted) return;
Future.delayed(Duration.zero).then((_) {
Navigator.of(context).pop();
});
}
}
不要将上下文直接存入自定义 类,如果您不确定您的小部件是否已安装,请不要在异步后使用上下文。
做这样的事情:
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),
);
}
}
只需将导航器或任何需要上下文的内容保存到函数开头的变量
myAsyncMethod() async {
final navigator = Navigator.of(context); // 1
await someFuture();
navigator.pop(); // 2
}
请勿在异步间隙中使用 BuildContext。
存储 BuildContext 供以后使用很容易导致难以诊断的崩溃。异步间隙隐式存储 BuildContext,是编写代码时最容易忽略的部分。
当从 StatefulWidget 使用 BuildContext 时,必须在异步间隙后检查已安装的 属性。
所以,我想,你可以这样使用:
好:
class _MyWidgetState extends State<MyWidget> {
...
void onButtonTapped() async {
await Future.delayed(const Duration(seconds: 1));
if (!mounted) return;
Navigator.of(context).pop();
}
}
差:
void onButtonTapped(BuildContext context) async {
await Future.delayed(const Duration(seconds: 1));
Navigator.of(context).pop();
}
我注意到我的项目中有一个新的 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{
final buildContext context;
const MyCustomClass({required this.context});
myAsyncMethod() async {
await someFuture();
# if (!mounted) return;
Future.delayed(Duration.zero).then((_) {
Navigator.of(context).pop();
});
}
}
不要将上下文直接存入自定义 类,如果您不确定您的小部件是否已安装,请不要在异步后使用上下文。
做这样的事情:
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),
);
}
}
只需将导航器或任何需要上下文的内容保存到函数开头的变量
myAsyncMethod() async {
final navigator = Navigator.of(context); // 1
await someFuture();
navigator.pop(); // 2
}
请勿在异步间隙中使用 BuildContext。
存储 BuildContext 供以后使用很容易导致难以诊断的崩溃。异步间隙隐式存储 BuildContext,是编写代码时最容易忽略的部分。
当从 StatefulWidget 使用 BuildContext 时,必须在异步间隙后检查已安装的 属性。
所以,我想,你可以这样使用:
好:
class _MyWidgetState extends State<MyWidget> {
...
void onButtonTapped() async {
await Future.delayed(const Duration(seconds: 1));
if (!mounted) return;
Navigator.of(context).pop();
}
}
差:
void onButtonTapped(BuildContext context) async {
await Future.delayed(const Duration(seconds: 1));
Navigator.of(context).pop();
}