8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Flutter Hooksを使用して状態管理をスッキリと!

Last updated at Posted at 2024-04-15

Flutter Hooks の概要

Flutter Hooksとは、Reactの Hooks にインスパイアされた、
Flutterアプリで状態管理を行うためのパッケージです。

このパッケージを使用することで、状態を保持するための
StatefulWidgetState クラスの使用が不要になり、
シンプルで直感的なコードを記述することができるようになります。

Flutter Hooksの特徴

  • 状態フック: useState を使用して、状態を保持することができます。これにより、 StatefulWidget の使用を回避し、状態をより直感的に管理できます。

  • useEffectフック: useEffect を使用して、ウィジェットのレンダリング後に関数を
    実行します。これにより、画面遷移やAPIリクエストなどの副作用を
    簡単に扱うことができます。

  • コンテキストフック: useContext を使用して、コンテキストを取得します。
    これによって、ウィジェットツリーの深い階層にある値を簡単に参照できます。

  • その他のフック: その他にも、 useMemouseCallbackuseReducer など、
    さまざまなフックが提供されています。これらのフックを組み合わせることで、
    より柔軟な状態管理が可能になります。

Flutter Hooksを採用するメリット

  • シンプルなコード: 状態管理や副作用の処理が簡潔になり直感的なコードを
    記述できるため、開発者はコードの可読性を向上させることができます。

  • 再利用性の向上: 画面内で必要な初期処理や、ステートで保持する内容を
    build メソッド内に書くことができます。

  • パフォーマンスの向上: Hooksを使用すると、ウィジェットの再ビルドが
    最小限に抑えられます。これにより、不必要な再レンダリングが減少し、
    アプリケーション全体のパフォーマンスが向上します。

基本メソッド

Flutter Hooks では、 HookWidget を継承したウィジェットを作成し、
use で始まるフックを使用します。

HookWidgetを継承
class MyApp extends HookWidget {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

riverpod の機能も同時に使用する場合は、 hooks_riverpod をimportした上で、 HookConsumerWidget を使用します。

代表的なフックには以下のようなものがあります。

useState

state を管理するための関数です。
初期値を引数に渡すと、その値を state として保持します。

値を更新する、参照する場合は、 value メソッドを使用します。
useState が変数の状態を監視しているため、 value メソッドを使用することで、
画面が再描画され、値を更新することが可能になります。

import 'package:flutter_hooks/flutter_hooks.dart';

// HookWidgetを継承
class CounterView extends HookWidget {
  @override
  Widget build(BuildContext context) {
    // useStateフックを使用
    final count = useState(0);

    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Count: ${count.value}'),
            ElevatedButton(
              onPressed: () => count.value++, // 状態を更新
              child: Text('Increment'),
            ),
          ],
        ),
      ),
    );
  }
}

useEffect

初回描画時、または特定の値が更新されたタイミングで呼び出す処理を記載する関数です。

final count = useState(0);
useEffect(() {
  // 初回描画時、countが変更されるたびに実行される
  print('Count changed: ${count.value}');
  
  //  ウィジェットが破棄される時に呼び出される
  return () => print('Cleanup');
}, [count.value]);

第一引数には実行したい関数を、第二引数には変更を検知したい変数を配置します。
第二引数は配列で定義することができるため、変数を複数検知することも可能です。

useMemoized

メモ化された値を返す関数です。
値が変更されない限り、前回計算された値が再利用されます。

メモ化とは?

同じ結果を返す処理について初回のみ処理を実行して、記録しておき、
値が必要になったら2回目以降は前回の処理結果を計算することなく、
値を得られるようにすることを言います。

メモ化によって都度計算する必要がなくなり、同じ結果を呼び出すため、
パフォーマンスの最適化が期待できます。

  • 第一引数: メモ化したい重い計算や作成処理などを行う関数を渡します。
    この関数の戻り値がメモ化されます。
  • 第二引数: この配列に含まれる値が変更された場合のみ、引数の関数が再実行されます。

以下の例では、2つの数値 ab の合計値を計算する関数を useMemoized
メモ化しています。 ab が変更されない限り、合計値の計算は行われません。

int sum(int a, int b) => a + b;

// ...

final a = useState(1);
final b = useState(2);
final totalSum = useMemoized(() => sum(a.value, b.value), [a.value, b.value]);

特に計算コストが高い処理で有効です。
例えば、データの加工、フィルタリング、ソートなどの操作でよく利用されます。

ただし、メモ化されたデータが変更される可能性がある場合は、
useState+ディープコピーなどで対処する必要があります。

まとめ

Flutter Hooks は、Reactの Hooks に似た状態管理ロジックを導入するパッケージです。
このパッケージを使用することで、 StatefulWidget を使わずに状態を
管理することができ、コードの可読性と保守性が向上します。
フックの種類も豊富なので、様々なユースケースに対応することができます。

参考資料

告知

最後にお知らせとなりますが、イーディーエーでは一緒に働くエンジニアを
募集しております。詳しくは採用情報ページをご確認ください。

みなさまからのご応募をお待ちしております。

8
4
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
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?