0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Flutter】context.mountedの使いどころ

Last updated at Posted at 2025-01-19

遭遇したケース

Fltterの実装では必要不可欠なBuildContext型のcontext

実態はWidgetと付随して作成されるWidgetの参照情報等を保持しているElementというオブジェクトのことです

そのcontextを使用するメソッドを作成して、引数として渡そうとすると、以下の警告が出ました

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' チェックで使用を保護してください。

なるほど🤔
確かに警告が出ていた箇所は非同期処理を使っていました

非同期処理中の別スレッドの処理でcontextの情報が書き替わる可能性がありますよね

すでにツリーから削除されているWidgetを使った処理が実行されることによるクラッシュやエラーを防ぐための警告だったんですね

解決策

ここで活躍するのがcontext.mountedです!
警告文にもあるように、BuildContextが用意してくれているmoutedを使えば解決できます

mountedとは対象のWidgetがツリーに存在しているか否かを示すbool値です
trueであればツリーに存在していることを表し、falseであれば既に使用されていない状態を表します

つまり、mountedがfalseの場合にcontextを使った処理を実行しないように実装すればよいということですね

今回の実装では、単純にifを使って修正しました
こんな感じで👇

void _closePage(BuildContext context) {
    if (context.mounted) {
      Navigator.pop(context); // 画面を閉じる
    }
}

(画面を閉じるだけのメソッドになってますが実際にはもう少し処理があります)

if (!context.mounted) retuern;で早期リターンを使っても良さそうですね

余談

mountedは他にも不要な処理が実行されることを防ぐことで、メモリリーク防止やパフォーマンス向上目的でも使われることがあるみたいですね

ただ、警告の修正時にAIからは以下のアドバイスをいただきました

非同期処理を含むコンストラクターやプロパティは、非同期ファクトリメソッドやメソッドに変更することを検討してください

単に警告が出ないように修正するだけではなく、そもそも警告が出ないような設計を考えることが必要なのかも...

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?