Zenn
🤝

FlutterのContext備忘録

2025/03/16に公開

Flutterのcontextについてまとめ

Context関連で躓くことが多々あるので、理解を深めるのとその都度見返せるようにまとめます。

Contextとは何か?

Contextは、Flutterアプリケーションにおいてウィジェットツリーの位置情報や、アプリケーション全体で共有される重要な情報(テーマ、ローカライゼーション、ナビゲーション等)へのアクセスを提供するオブジェクトです。

BuildContextの役割と重要性

BuildContextは、ウィジェットがウィジェットツリー内のどの位置に配置されているかを示す重要な要素です。

  • 祖先ウィジェットへのアクセスが可能
  • Theme.of(context)やMediaQuery.of(context)などの機能が利用可能
  • ナビゲーションやダイアログの表示が制御可能

Contextの伝播の仕組み

Contextは親ウィジェットから子ウィジェットへと自動的に伝播されます

  • InheritedWidgetを通じて下位のウィジェットにデータを提供
  • Element TreeでのWidget間の関係性を管理

InheritedWidgetによるデータの提供

  • InheritedWidgetは、ウィジェットツリーの下位に位置するすべての子ウィジェットにデータを効率的に提供します
  • 例えば、ThemeMediaQueryもInheritedWidgetを使用しています
  • データの更新があった場合、dependOnInheritedWidgetOfExactTypeを使用している子ウィジェットのみが再ビルドされます

Element Treeでの関係性管理

  • Flutterは内部でElement Treeを構築し、Widgetの関係性を管理します
  • 各Elementは対応するWidgetとBuildContextを保持します
  • BuildContextを通じて、上位のInheritedWidgetにアクセスする際は以下の流れで処理されます:
    1. 現在のElementから開始
    2. 親Elementを順次探索
    3. 目的のInheritedWidgetが見つかるまで遡る
    4. 見つからない場合はエラーを発生

伝播の制限事項

  • contextは常に上から下への一方向の伝播のみ
  • 兄弟ウィジェット間での直接的なデータ共有は不可能
  • グローバルな状態管理が必要な場合は、Provider等の状態管理を使用する

Contextの正しい使い方とベストプラクティス

  • BuildContextは必ずbuildメソッド内で使用
  • StatefulWidgetではState内のcontextを使用
  • contextの保持は避け、必要な時に都度参照
  • グローバルなcontextの使用は避ける

クロージャー内での注意点

クロージャー内でcontext.read<T>()を使ってプロバイダーの値を読み取る実装をした場合、
その画面を閉じることでcontextが無効(古いcontextを保持したまま)になりcontextの参照ができなくなることがある。
なので極力クロージャー内でのキャプチャはしない方が良い。

Discussion

ログインするとコメントできます