【Flutter】FlutterHooksでuseStateを使った簡単な状態管理の方法

Flutter状態管理

Flutter開発において人気の高いFlutterHooksについて解説していきます。
今回はuseStateにフォーカスして解説いたします。

ぜひご覧ください。

FlutterHooksとは?

公式記載

Hooks are a new kind of object that manage the life-cycle of a Widget. They exist for one reason: increase the code-sharing between widgets by removing duplicates.

日本語訳

フックは、ウィジェットのライフサイクルを管理する新しい種類のオブジェクトです。存在する理由は1つ。重複を削除することで、ウィジェット間のコード共有を増やすためです。

つまり、以下のようなイメージです。

  • 状態管理をするための一つのオブジェクト
  • StatefulWidgetよりも簡潔にかける
  • 1対1のようなシンプルな状態管理に活かせる

Riverpodを併用できる、 hooks_riverpod については、今回は省略します。

公式Hooksライブラリページ

flutter_hooks | Flutter package
A flutter implementation of React hooks. It adds a new kind of widget with enhanced code reuse.

FlutterHooksを使用するメリット

  • シンプルな記載が可能

これが1番のメリットかなと思います。
これにより可読性が上がりコードがスッキリします

これがStatefulWidgetの場合、initStateなり、コードが長くなりがちになります。StatefulWidgetがダメというわけではないのですが、一長一短かなと思います。

詳しくは下記でStatefulWidetとhooksを比較していますのでより理解が深まると思うのでご覧ください。

useStateとは?

FlutterHooksで基本的な関数の一つがuseStateです。

useStateについては以下のようなイメージです。

  • FlutterHooksで基本的な関数の一つ
  • Stateを管理するための関数
  • 値の更新を監視できる
  • 1対多(Riverpodのような)状態管理はできない

次からは具体的な使い方を見ていきましょう。

具体的な使用方法

必要な準備(パッケージのインストール)

flutter_hookspubspec.yamlに定義する。

バージョンは適宜調整してください。

dependencies:

  flutter:

    sdk: flutter

  flutter_hooks: ^0.20.5

HookWidgetの設定

指定のクラスにHookWidgetを設定

class MyHomePage extends HookWidget {

useStateの定義

実際にuseStateを定義します。

下記は、int型の0という数字がデフォルト設定のuseStateになります。

useState();の()内に記載することでStateを管理できます。
これはStringやMap等も可能です。

var count = useState(0);

この際に下記のようにbuiid関数内で書くことに注意してください。

class MyHomePage extends HookWidget {
  const MyHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    var count = useState(0);

Stateの変更

実際にStateを変更してみます。
今回は数字が1ずつ上がるというシンプルな実装です。

Count.valueと書くことで具体的な数字を操作できます。

下記の場合だと、0で設定した値にボタンをおすと1上がる(インクリメント)するように設定しています。

ElevatedButton(
  onPressed: () {
    count.value++;
  },
  child: const Text('Increment'),
),

ここでuseState(0)は、初期値0の状態を作成しています。

count.valueで現在の値を取得でき、count.value = 新しい値のように変更できます。

Stateの表示

④と同じようにvalueとすることで表示可能です。

今回はint型を表示するためStringへ変換しています。

 Center(
  child: Text(count.value.toString()),
),

全体像

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends HookWidget {
  const MyHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    var count = useState(0);

    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter Demo'),
      ),
      body: Column(
        children: [
           Center(
            child: Text(count.value.toString()),
          ),
          ElevatedButton(
            onPressed: () {
              count.value++;
            },
            child: const Text('Increment'),
          ),
        ],
      ),
    );
  }
}

注意点

下記2点には注意が必要です。

  • 初期値の設定タイミング

 useStateはビルド時に初期化されますが、初期値の設定が重い計算を伴う場合、パフォーマンスに影響を与える可能性があります。

対策: 初期値の計算が複雑な場合は、useMemoizedや遅延初期化の方法を検討が必要があります。

  • 状態のスコープに注意

– useStateで管理する状態は、そのフックが存在するウィジェットのスコープ内に限定されます。

対策: 親ウィジェットや他のウィジェットと状態を共有する必要がある場合は、別の状態管理方法(例: hooks_riverpodなど)を検討する必要があります。

まとめ

  • FlutterHooksとuseStateを使うことで、状態管理がシンプルに行える。
  • 小規模なプロジェクトや1対1の状態管理には最適
  • 状況に応じてStatefulWidgetや他のライブラリ(例: hooks_riverpod)も検討する

上記のようなメリットやデメリットがあるのでうまく使い分けながらぜひFlutterHooksの使い方についてマスターしてください。

ではまた。

コメント

タイトルとURLをコピーしました