Flutter: Navigatorで、Do not use BuildContexts across async gaps の警告が出る

2022/7/24 Flutter エラー・バグ日記 

画面遷移をさせるため、ごく一般的な「Navigator.pushReplacement(context, ・・・」のような記述をしたところ、警告の波線が出るようになった。

 

カーソルを当てて内容を見ると、「Do not use BuildContexts across async gaps.」という警告コメントが表示される。

 

本記事はライトな日記思考で書いているので、詳細説明はしておらず、基本、テキストのみで画像とかは載せておりません。。m(_ _)m

解説記事ではないため、解決していない内容や、その時々の間違った解釈を述べてしまっている可能性が大いにありますので、何卒、ご了承ください。

 

警告コメントの脇にある「Documentation」のリンクをたどると、以下の説明ページに飛んだ。

 

 

内容を読んだ自分なりの理解としては、非同期処理中に、「Navigator」のように、contextを渡す処理があると、非同期処理から戻ってきたときに、既に画面遷移が終わっていて、元の画面のcontextが無くなっているのでエラーになる、という状況を防ぎましょう、ということらしい。

 

上記「Documentation」にある対策は、「Navigator」の前に、「if (!mounted) return;」をつけるというもの。

 

class _MyWidgetState extends State<MyWidget> {
  ...

  // 非同期処理(async, await)の中でcontextを渡している
  void onButtonTapped() async {
    await Future.delayed(const Duration(seconds: 1));

    // contextを渡す前に、contextが現在のWidgetツリー内に存在しているかどうかチェック
    // 存在しなければ、画面遷移済を意味するので、以降の画面遷移処理は行わない
    if (!mounted) return;

    Navigator.of(context).pop();
  }
}

 

要は、contextが無くなっていたら、早期リターンしてNavigatorを実行させないようにする、ということだと思われる。

 

※「mounted」プロパティについては以下に説明がある。Stateful Widgetのオブジェクトが、現在のWidgetツリー内に存在するか否かを示すbool型のプロパティのこと(存在しなければ、既に別のWidgetツリーに移っている=画面遷移している、ということだろう)。

 

 

確かに過去に作成していたアプリで、画面遷移をした後に、

 

This widget has been unmounted, so the State no longer has a context

 

というエラーが出たことがよくあった。

 

このとき、ググって対策を調べたら、「if (mounted) { }」で処理をラップすると良い、という情報があり、これでエラーを回避していた。

 

 

恐らく今回の警告は、この危険性を事前に察知してくれるものなのだろう。

 

「Documentation」によると、この警告は「Linter v1.1」となっている。

 

Flutter3にアップグレードして新規プロジェクトを作成すると、「pubspec.yaml」には「flutter_lints: ^2.0.0」がインポートされているので、恐らくアップグレードしたことでこの警告が機能するようになったのだと思われる(アップグレード前は「flutter_lints: ^1.0.0」だった)。

 

警告が出ると厄介に感じがちだが、こうして先回りしてエラーを防いでくれるのは、非常にありがたい。

 

\ Flutterの学習で役立ったコンテンツ・書籍 /

 

 

 


Dart入門 – Dartの要点をつかむためのクイックツアー
タイトルとURLをコピーしました