🤝
FlutterのContext備忘録
Flutterのcontextについてまとめ
Context関連で躓くことが多々あるので、理解を深めるのとその都度見返せるようにまとめます。
Contextとは何か?
Contextは、Flutterアプリケーションにおいてウィジェットツリーの位置情報や、アプリケーション全体で共有される重要な情報(テーマ、ローカライゼーション、ナビゲーション等)へのアクセスを提供するオブジェクトです。
BuildContextの役割と重要性
BuildContextは、ウィジェットがウィジェットツリー内のどの位置に配置されているかを示す重要な要素です。
- 祖先ウィジェットへのアクセスが可能
- Theme.of(context)やMediaQuery.of(context)などの機能が利用可能
- ナビゲーションやダイアログの表示が制御可能
Contextの伝播の仕組み
Contextは親ウィジェットから子ウィジェットへと自動的に伝播されます
- InheritedWidgetを通じて下位のウィジェットにデータを提供
- Element TreeでのWidget間の関係性を管理
InheritedWidgetによるデータの提供
- InheritedWidgetは、ウィジェットツリーの下位に位置するすべての子ウィジェットにデータを効率的に提供します
- 例えば、
Theme
やMediaQuery
もInheritedWidgetを使用しています - データの更新があった場合、dependOnInheritedWidgetOfExactTypeを使用している子ウィジェットのみが再ビルドされます
Element Treeでの関係性管理
- Flutterは内部でElement Treeを構築し、Widgetの関係性を管理します
- 各Elementは対応するWidgetとBuildContextを保持します
- BuildContextを通じて、上位のInheritedWidgetにアクセスする際は以下の流れで処理されます:
- 現在のElementから開始
- 親Elementを順次探索
- 目的のInheritedWidgetが見つかるまで遡る
- 見つからない場合はエラーを発生
伝播の制限事項
- contextは常に上から下への一方向の伝播のみ
- 兄弟ウィジェット間での直接的なデータ共有は不可能
- グローバルな状態管理が必要な場合は、Provider等の状態管理を使用する
Contextの正しい使い方とベストプラクティス
- BuildContextは必ずbuildメソッド内で使用
- StatefulWidgetではState内のcontextを使用
- contextの保持は避け、必要な時に都度参照
- グローバルなcontextの使用は避ける
クロージャー内での注意点
クロージャー内でcontext.read<T>()を使ってプロバイダーの値を読み取る実装をした場合、
その画面を閉じることでcontextが無効(古いcontextを保持したまま)になりcontextの参照ができなくなることがある。
なので極力クロージャー内でのキャプチャはしない方が良い。
Discussion