⚠️
[エラー]Don't use 'BuildContext's across async gaps.
タイトルのようなエラーが出てたので、修正しました。
このエラーが出た場面
StatefulWidgetを継承したクラス内の非同期処理で、awaitの後にcontextを使用したpush処理を記述した際にエラーが出現した。
void getLocationData() async {
dynamic weatherData = await WeatherModel().getLocationWeather();
Navigator.push(
// ▼error
context,
MaterialPageRoute(
builder: (ctx) => LocationScreen(
data: weatherData,
),
),
);
}
和訳
Don't use 'BuildContext's across async gaps.
Try rewriting the code to not use the 'BuildContext', or guard the use with >a 'mounted' check.
エラー全文和訳すると下記のようになる。
BuildContextを非同期のギャップで使用しないこと。
BuildContext'を使わないようにコードを書き換えるか、'mounted'チェックで使用をガードする。
なぜ、このようなエラーが出たか
エラーの文言から、awaitの処理の後にcontextを使用した処理を行おうとしたことが原因。
contextというのは、構築されているWidgetの最新の状態(=WidgetTree内の位置付け)
を管理しているもの。
awaitで次の処理の再開まで時間がかかる。その最中で、Widgetが無効にされている(現在のWidgetが破棄される)とcontextを使用した処理でエラーになるため、注意されている。
どうすれば解決できるか
エラー文の通り、'mounted'を使ってチェックする。
'mounted'チェックで使用をガードする。
mountedとは
Stateオブジェクトが、最新の状態で構築されているか(=WidgetTree内に存在するか)どうかを確認する。
有効ならtrue,、無効ならfalseを返す。
コード修正
if文でmountedのtrue,faleseを確認して、Navigator.push処理させる。
void getLocationData() async {
dynamic weatherData = await WeatherModel().getLocationWeather();
if (mounted) {
Navigator.push(
context,
MaterialPageRoute(
builder: (ctx) => LocationScreen(
data: weatherData,
),
),
);
}
}
Discussion