サイトアイコン 【TechGrowUp】

Flutter開発入門49 Providerパターンを使ったシンプルな状態管理

はじめに

Flutterでアプリケーションを開発する際、状態管理は避けて通れない課題です。特に規模が大きくなるアプリでは、効率的に状態を管理し、UIとビジネスロジックを分離する設計が重要になります。そこで登場するのがProviderパターンです。FlutterのProviderパッケージは、公式が推奨する状態管理の方法で、シンプルでありながら強力です。

この記事では、Flutterの公式ドキュメントに基づき、Providerパターンによるシンプルな状態管理について解説します。初めてFlutterで状態管理を学ぶ方にも理解しやすいように、基本的な概念から実際のコード例まで紹介します。

Providerパターンとは

Providerパターンは、Flutterでの状態管理を簡潔かつ効率的に行うための設計パターンです。Providerは依存性注入の仕組みを提供し、データの共有とUIの更新を容易にします。特に、状態が変わるたびにUIをリビルドする必要がある場合に便利です。

Providerパターンの主な特徴

Providerパターンの基本的な使い方

1. セットアップ

まず、pubspec.yamlファイルにproviderパッケージを追加します。

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.0

その後、依存関係をインストールします。

flutter pub get

2. Providerの構造

Providerパターンでは、状態を管理するクラスと、そのクラスを使ってUIを更新する流れが基本です。大まかな構造は以下の通りです。

シンプルなカウンターアプリの例

1. モデルクラスの作成

まずは、状態を管理するためのモデルクラスを作成します。このクラスでは、カウンターの値を保持し、値を増加させるメソッドを定義します。

import 'package:flutter/foundation.dart';

class CounterModel with ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }
}

解説

2. Providerを使ったウィジェットの構築

次に、Providerを使ってアプリケーション全体でこのモデルクラスを提供します。Providerで状態をラップし、Consumerウィジェットを使ってUIを更新します。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'counter_model.dart'; // モデルクラスをインポート

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => CounterModel(),
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CounterScreen(),
    );
  }
}

class CounterScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Counter App with Provider')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('You have pushed the button this many times:'),
            Consumer<CounterModel>(
              builder: (context, counter, child) {
                return Text(
                  '${counter.count}',
                  style: Theme.of(context).textTheme.bodySmall,
                );
              },
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<CounterModel>(context, listen: false).increment();
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

解説

複雑な状態管理への拡張

Providerパターンは、シンプルなアプリから複雑なアプリまでスケーラブルに対応できます。例えば、以下のような機能を追加することが可能です。

1. 複数のProviderを使用する

MultiProviderを使うことで、複数の状態を同時に管理できます。たとえば、カウンターの状態とユーザーの認証状態をそれぞれ管理する場合に便利です。

MultiProvider(
  providers: [
    ChangeNotifierProvider(create: (context) => CounterModel()),
    ChangeNotifierProvider(create: (context) => AuthModel()),
  ],
  child: MyApp(),
)

2. 非同期処理との統合

Providerは非同期データにも対応可能です。例えば、APIリクエストを実行して、取得したデータをUIに反映することができます。FutureProviderStreamProviderを使えば、非同期データを簡単に扱えます。

Providerパターンのメリットとベストプラクティス

メリット

  1. シンプルなAPIProviderの使い方は非常にシンプルで、導入が簡単。
  2. テストがしやすい:ビジネスロジックとUIが分離されているため、テストが容易。
  3. パフォーマンスが高い:状態が変更されたときに必要な部分だけをリビルドするため、パフォーマンスに優れています。

ベストプラクティス

まとめ

FlutterのProviderパターンは、シンプルかつ強力な状態管理方法を提供します。ChangeNotifierを使って状態を簡単に管理し、ConsumerProvider.ofでUIに反映することで、効率的な状態管理が可能になります。また、複数のプロバイダや非同期処理も簡単に扱えるため、スケーラブルなアプリケーション開発が可能です。

モバイルバージョンを終了