LoginSignup
0
0

【Flutter】状態管理

Last updated at Posted at 2023-12-10

chatGPT に立ててもらったスケジュールに準じてFlutterの状態管理を勉強。

  • Day 5: Flutterの状態管理
    • 状態管理の必要性とFlutterの提供する方法を学ぶ
    • 状態の共有と更新の方法を理解する

状態管理とは

ログインしたり アイテムをカートに入れるアニメーション | 公式のgif

  • なんらかのきっかけから、UIが変わるために「状態管理」する必要がある。
  • たとえばユーザーがログインすれば、ログインユーザーのみの画面に遷移するとか、ECアプリでアイテムを追加したらカートの中身が反映されるとか。
  • 3つの方法で状態管理ができる
    • setState
      • リビルド(画面全体の更新)が必要になる⇒重くなる可能性が増える
    • Provider
      • リビルドせずピンポイントの更新が可能
      • 公式に推奨されてる
    • Riverpod
      • Providerの改良版らしい
      • リビルドせずピンポイントの更新が可能
      • Flutter に依存しない(pure dart)⇒学習コストが高くなることもある

状態の共有と更新の方法

学習コスト高すぎると挫折しそうなので以下はProviderにしました。

pubspec.yaml にproviderを導入することを記載

dependencies:
  provider: ^6.0.2

ターミナルで依存関係として追加

$ flutter pub add provider

Providerを実装

chatGPTにもらったサンプルソースに分からなかったところをコメントで追加

サンプルソース
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    ChangeNotifierProvider( // ChangeNotifierを使いたいウィジェットを子にする。ChangeNotifierのインスタンスを提供する。
      create: (context) => CounterProvider(),
      child: MyApp(),
    ),
  );
}

class CounterProvider extends ChangeNotifier { // ChangeNotifier は変更の監視を可能にさせるクラス
  int _counter = 0;

  int get counter => _counter;

  void incrementCounter() {
    _counter++;
    notifyListeners();
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Counter App with Provider'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Consumer<CounterProvider>( // Consumer<任意のModel> : 提供されたモデルを使うためのWidget Consumerで囲われた部分が更新対象
                builder: (context, counterProvider, child) { // (context, ChangeNotifierのインスタンス, child)
                  return Text('Count: ${counterProvider.counter}');
                },
              ),
              ElevatedButton(
                onPressed: () {
                  Provider.of<CounterProvider>(context, listen: false) // <任意のModel>にアクセス メソッドのみ呼び出したいときはlistenをfalseにすると再構築されない 試しにtrueにしてみたら画面上の数は更新されなかった
                      .incrementCounter();
                },
                child: Text('Increment'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

参考

公式ドキュメント

provider

Riverpod

Zenn

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0