Flutterの状態管理(Hooks・Riverpod)
2025 年 10 月 22 日 by sumikawahはじめに
現在、Flutterでアプリ開発を行うにあたり、さまざまな状態管理の方法があることを学びました。
その中でも、Hooks と Riverpod は開発の効率化やコードの可読性向上に大きく貢献する技術です。
今回はこの2つの仕組みについて整理し、理解を深めることを目的とします。
状態管理とは?
Flutterにおける状態管理とは、アプリの「状態(State)」をどのように保持し、更新し、UIに反映させるかを管理することです。
たとえば、ボタンを押したときにカウントが増えるような画面では、カウント値(状態)を保持し、それをUIに反映させる必要があります。
Hooksとは?
Flutter Hooks は、React Hooksの考え方をFlutterに取り入れたパッケージです。
StatefulWidgetでよく使う「状態を保持する処理」や「ライフサイクル処理」を、よりシンプルに書けるようにする仕組みです。
特徴
- ・StatefulWidget を使わずに状態を管理できる
・useState
やuseEffect
など、直感的な関数スタイルで状態を扱える- ・コードの重複を減らし、UIロジックを整理しやすい
以下は、Hooksを使ったカウンターアプリの例です。
import 'package:flutter_hooks/flutter_hooks.dart'; class CounterPage extends HookWidget { @override Widget build(BuildContext context) { // useStateで状態を定義(countは0からスタート) final count = useState(0); return Scaffold( body: Center( // 現在のcountの値を表示 child: Text('${count.value}'), ), floatingActionButton: FloatingActionButton( // ボタン押下でcountの値を+1 onPressed: () => count.value++, child: Icon(Icons.add), ), ); } }
Riverpodとは?
Riverpod は、Providerの改良版として開発された状態管理パッケージです。
依存関係の明示的な管理、テストのしやすさ、グローバルアクセスの安全性を重視しています。
特徴
- ・グローバル変数を使わずに状態を安全に管理できる
- ・Provider間の依存関係を明確に定義できる
- ・ホットリロードやテストとの相性が良い
- ・Null安全や非同期処理(FutureProvider、StreamProviderなど)にも対応
以下は、StateProvider
を使ったシンプルな例です。
import 'package:flutter_riverpod/flutter_riverpod.dart'; // 状態を定義するProvider final counterProvider = StateProvider((ref) => 0); class CounterPage extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { // Providerの状態を監視 final count = ref.watch(counterProvider); return Scaffold( body: Center( // 現在のcountの値を表示 child: Text('$count'), ), floatingActionButton: FloatingActionButton( // ref.readで状態を更新 onPressed: () => ref.read(counterProvider.notifier).state++, child: Icon(Icons.add), ), ); } }
Hooks × Riverpod の組み合わせ
Flutter Hooks と Riverpod は、それぞれ独立して使うこともできますが、
一緒に使うことでさらに柔軟で効率的な状態管理が可能になります。
HooksはWidget内の状態やライフサイクルを簡潔に扱うのに適しており、
Riverpodはアプリ全体の状態を安全に管理する仕組みを提供します。
この2つを組み合わせることで、UIとロジックを完全に分離しつつ、シンプルなコードで開発できるようになります。
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; // Riverpodでグローバル状態を定義 final counterProvider = StateProvider((ref) => 0); // HooksとRiverpodを組み合わせたWidget class CounterPage extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { // Riverpodの状態を監視 final count = ref.watch(counterProvider); // Hooksでローカルな状態を保持(例: 偶数・奇数判定) final isEven = useState(true); // countが変わるたびにisEvenを更新 useEffect(() { isEven.value = count % 2 == 0; return null; }, [count]); return Scaffold( body: Center( child: Text( 'Count: $count (${isEven.value ? "Even" : "Odd"})', style: TextStyle(fontSize: 20), ), ), floatingActionButton: FloatingActionButton( onPressed: () => ref.read(counterProvider.notifier).state++, child: Icon(Icons.add), ), ); } }
まとめ
- ・Flutterの状態管理は、アプリの規模拡大に伴い重要性が増します。
- ・Hooksは、Widgetの状態管理をシンプルにし、Riverpodは依存関係やスコープを安全に扱える仕組みです。
- ・両者を組み合わせることで、コードの見通しが良く、保守性の高いアプリを実現できます。