Flutter開発入門9 InheritedWidgetについて

Flutter

はじめに

 Flutterでは、状態管理はアプリケーションの核心部分を担う重要な要素です。その中でもInheritedWidgetは、ツリー内のWidget間でデータを効率よく共有するための基本的な仕組みとして広く使われています。本記事では、InheritedWidgetの基本的な役割と、その使い方について解説します。前回のFlutter入門開発はこちらです。

InheritedWidgetとは

 InheritedWidgetは、Flutterのウィジェットツリー内で親から子にデータを効率よく伝達するために使用される特殊なWidgetです。通常、アプリケーションの状態(ステート)は上位のWidgetで管理され、それをツリー内の複数の子Widgetで共有する必要があります。このとき、InheritedWidgetを活用することで、効率的かつ簡潔にデータを渡すことが可能になります。

InheritedWidgetの基本構造

 InheritedWidgetは基本的に次のような構造を持ちます:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('InheritedWidget Example')),
        body: MyInheritedWidget(
          data: 'Hello, Tech Grow Up!',
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              TextWidget(),
            ],
          ),
        ),
      ),
    );
  }
}

class MyInheritedWidget extends InheritedWidget {
  final String data;

  MyInheritedWidget({required this.data, required Widget child})
      : super(child: child);

  @override
  bool updateShouldNotify(MyInheritedWidget oldWidget) {
    return oldWidget.data != data;
  }

  static MyInheritedWidget? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
  }
}

class TextWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final inheritedWidget = MyInheritedWidget.of(context);
    return Center(
      child: Text(
        inheritedWidget?.data ?? 'No data found',
        style: const TextStyle(fontSize: 24),
      ),
    );
  }
}

解説

  • MyInheritedWidgetクラス: ここでは、InheritedWidgetを継承してカスタムウィジェットを作成しています。dataフィールドに保持される値を、ツリー内の子Widgetに伝達します。
  • updateShouldNotifyメソッド: これは、ウィジェットが更新されるかどうかを決定するためのメソッドです。ここでは、新しいデータが古いデータと異なる場合にtrueを返すようにしています。
  • ofメソッド: MyInheritedWidgetのインスタンスをツリー内で取得するための静的メソッドです。このメソッドを使って、子Widgetはデータを取得します。
  • TextWidgetクラス: ofメソッドを使用して、InheritedWidgetからデータを取得し、それを表示しています。

InheritedWidgetの活用シーン

 InheritedWidgetは、以下のようなシーンで効果的に活用できます。

  1. テーマの管理: アプリ全体で使用されるテーマデータ(例:カラーやフォント)を一元管理するために、InheritedWidgetを使って、全ての子Widgetにテーマデータを伝達します。
  2. ローカライズ: 多言語対応アプリで、ユーザーが選択した言語に基づいて文字列を表示する場合、InheritedWidgetを使用して、選択された言語のデータをツリー全体に伝達します。
  3. アプリ全体の設定: ユーザーの設定(例:ダークモードのオン/オフ)をアプリ全体に反映させるために、InheritedWidgetを使用します。

InheritedWidgetのメリットと注意点

メリット

  • シンプルなコード構成: アプリケーション全体でデータを共有するためのコードがシンプルで読みやすくなります。
  • 効率的なデータ伝達: InheritedWidgetを使用することで、ツリーの特定の部分だけに必要なデータを渡すことができ、無駄な再レンダリングを防げます。

注意点

  • 再レンダリングの管理: updateShouldNotifyメソッドの実装に注意しないと、不要な再レンダリングが発生する可能性があります。これにより、パフォーマンスが低下する場合があります。
  • 他の状態管理と比較したシンプルさ: InheritedWidgetはシンプルですが、大規模なアプリケーションでは、ProviderRiverpodなど、より高度な状態管理ソリューションが適している場合があります。

まとめ

 InheritedWidgetは、Flutterにおける状態管理の基本を学ぶ上で非常に重要なコンポーネントです。簡単なアプリケーションであれば、このウィジェットを活用することで、効率的かつシンプルに状態管理を行うことができます。Flutterの状態管理に慣れていない方は、まずInheritedWidgetから学び、その後他の状態管理パッケージへと進んでいくと良いでしょう。

コメント