Riverpod の ConsumerWidget を使っていて 'DO NOT use BuildContext across asynchronous gaps.' が出たときの対応
Riverpod の ConsumerWidget を使っていて ‘DO NOT use BuildContext across asynchronous gaps.’ が出た場合、サジェストされる対応方法では解決しないので解決方法を記載する。
開発環境
- Flutter SDK: 3.0.5
- flutter_riverpod: 2.0.0-dev.9
本文
問題
下記のように、Riverpod の ConsumerWidget の build 関数内で await
の後に Navigator.pop(context);
を呼ぶようなコードを書いたとする。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
class AddPage extends ConsumerWidget {
const AddPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: AppBar(title: const Text('新規登録')),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
const ResultParts(),
ElevatedButton(
child: const Text('保存'),
onPressed: () async {
final result = await _save(context, ref);
if (result) {
const snackBar = SnackBar(
content: Text('保存しました'),
backgroundColor: Colors.green,
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
Navigator.pop(context, 'saved');
}
},
),
],
),
));
}
Future<bool> _save(BuildContext context, WidgetRef ref) async {
final result =
await ref.read(addPageProvider.notifier).save().then((value) {
return true;
}).catchError((err) {
showDialog<int>(
context: context,
barrierDismissible: false,
builder: (context) {
return ErrorDialog(e: err);
},
);
return false;
});
return result;
}
}
|
このとき Android Studio では下記の warning が出る。
DO NOT use BuildContext across asynchronous gaps.
上記のリンク先に対応方法が書いてあり、
と書くとのことなのだが、この mounted
というのが ConsumerWidget には存在しない。
対応
mounted
の代わりを探したが見つからなかったため、手っ取り早く await
の後に処理を呼ぶのを止めた。
then
で繋げてその中に処理を記述するようにする。
たとえば下記のように修正すると warning が出なくなる。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
class AddPage extends ConsumerWidget {
const AddPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: AppBar(title: const Text('新規登録')),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
const ResultParts(),
ElevatedButton(
child: const Text('保存'),
onPressed: () async {
await _save(context, ref);
},
),
],
),
));
}
Future<void> _save(BuildContext context, WidgetRef ref) async {
await ref.read(addPageProvider.notifier).save().then((value) {
const snackBar = SnackBar(
content: Text('保存しました'),
backgroundColor: Colors.green,
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
Navigator.pop(context, 'saved');
}).catchError((err) {
showDialog<int>(
context: context,
barrierDismissible: false,
builder: (context) {
return ErrorDialog(e: err);
},
);
});
}
}
|
その他今週の成果物
https://gitlab.com/k1350/flutter_anger_log
以上