mountedとは?
Flutterでは、ウィジェットがマウントされているかどうかを確認するために
mounted
プロパティが提供されています。
このプロパティは、ウィジェットが現在のウィジェットツリーに含まれていて、
描画されているかどうかを確認するためのプロパティです。
特に、非同期処理やWidgetのライフサイクルを超えて操作を行う場合に使用されます。
Widgetがツリーに追加されると、mounted
はtrue
に設定され、
一方、Widgetがツリーから削除された場合(新しい画面に遷移したときや、
親Widgetが削除されたときなど)、mounted
はfalse
に設定されます。
mounted
のチェックを行わない場合、例外が発生したり、
予期しない動作につながる可能性があるので、
WidgetのステートやUIを変更する操作を行う前には、
必ず mounted
の値をチェックすることが重要です。
使用理由
mounted
プロパティを使用する主な理由とメリットは以下の通りです。
1. Widgetのライフサイクルを適切に管理する
Widgetがウィジェットツリーから削除された後にステートを変更しようとするのを
防ぐことができます。これにより、不必要な例外やクラッシュを回避できます。
2. メモリリークを防ぐ
Widgetがアンマウントされた後に非同期処理が完了した場合、
その結果を処理しようとするとメモリリークが発生する可能性があります。
mounted
プロパティを使用することで、不要な処理を行わずにリソースを管理できるため、
メモリリークを防ぐことにも繋がります。
3. パフォーマンスの向上
不要な処理を行わずに済むことで、アプリのパフォーマンスが向上します。
Widgetがアンマウントされた後に無駄な処理を行うことがなくなるため、
リソースを効率的に使用できます。
4. コードの堅牢性の向上
予期せぬ状況でのエラーを回避できます。これにより、コードの堅牢性が向上し、
安定したアプリケーションを構築できます。
5. デバッグの容易性
Widgetのライフサイクルに関するエラーを特定しやすくなります。
これにより、デバッグが容易になり、開発効率が向上します。
使用例
例えば、StatefulWidget
でAPIからデータを非同期で取得する場合を考えてみましょう。
Widgetが fetchData
メソッドの完了前にウィジェットツリーから削除された場合、
そのWidgetのステートを更新しようとするとエラーが発生する可能性があります。
このような問題を回避するために、WidgetのステートやUIを変更する前には、
必ずmounted
の値をチェックする必要があります。
以下は、非同期処理でmounted
を使用する例です。
// StatefulWidgetの中で使用される
Future<void> fetchData() async {
final data = await someAsyncOperation();
if (mounted) {
setState(() {
// 取得したデータでWidgetのステートを更新
_data = data;
});
}
}
この例では、 fetchData
メソッドが非同期処理( someAsyncOperation
)を
実行しています。取得したデータでWidgetのステートを更新する前に、
mounted
の値をチェックしています。
もしWidgetがアンマウント(別の画面に遷移したり削除された場合)されていれば、
setState
の呼び出しをスキップし、エラーの発生を防いでいます。
mounted
を使用する場面は以下のような場合が想定されます。
- WidgetのステートやUIを変更する前
- 非同期処理、タイマー、Widgetのライフサイクルを超えて操作を行う場合
使い方
以下は、 mounted
プロパティを使用した例です。
class _MyWidgetState extends State<MyWidget> {
void _handleCallback() {
if (mounted) {
setState(() {
// ステートを更新する処理
});
}
}
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
// 別のWidgetからコールバック関数を呼び出す
someOtherWidget.callbackFunction = _handleCallback;
},
child: const Text('Update State'),
);
}
}
この例では、ボタンを押すと別のWidgetからコールバック関数が呼び出されます。
コールバック関数内でステートを更新するため、 mounted
のチェックが必要になります。
コールバック関数が呼び出された時点でWidgetがアンマウントされていた場合、
mounted
チェックを行わずに setState()
を呼び出すとエラーになってしまいます。
そのため、 mounted
チェックを行った上でステートを更新する必要があります。
mounted
判定を行わずに setState()
を呼び出した場合、
"setState() or markNeedsBuild() called during build"というエラーが発生する
可能性があります。これは、ビルドフェーズ中にステートが
変更されたことを示すエラーです。
注意点
mounted
プロパティを使用する際には、ウィジェットが破棄された後に
アクセスされる可能性があるため、そのことを考慮する必要があります。
ウィジェットがマウントされていない場合にアクセスすると、
エラーが発生する可能性がありますので、適切にチェックすることが重要です。
まとめ
mounted
プロパティを理解し、適切に使用することで、
Widgetのライフサイクルの変更を適切に処理し、アンマウントされたWidgetを
操作することによる問題を回避できるようになります。
特に非同期処理やWidgetのライフサイクルが複雑になる場合は、
mounted
プロパティの使用が必須となります。これを機にぜひ使用してみてください。
参考資料
告知
最後にお知らせとなりますが、イーディーエーでは一緒に働くエンジニアを
募集しております。詳しくは採用情報ページをご確認ください。
みなさまからのご応募をお待ちしております。