FlutterのBlocパターンを完全ガイド!初心者でもわかる状態管理と導入方法
生徒
「Flutterで複雑な画面の状態管理が難しいんです。Blocってよく聞きますが、どういう仕組みなんですか?」
先生
「FlutterのBloc(ブロック)パターンは、状態管理をロジックとUIで明確に分離する仕組みです。コードを整理しやすくなりますよ。」
生徒
「なるほど!Blocの導入方法や使い方を具体的に知りたいです!」
先生
「それでは、FlutterでのBlocの使い方を、導入手順から詳しく見ていきましょう!」
1. Blocパターンとは?Flutterの状態管理を明確にする仕組み
FlutterのBlocパターンとは、BLoC(Business Logic Component)の略で、UIとビジネスロジックを明確に分けて状態管理を行うアーキテクチャです。
ユーザーの操作(イベント)に応じて、状態(State)を変更し、その変更に基づいてUIが自動的に更新される流れを作ることができます。
Blocパターンは、保守性の高いコードを実現しやすく、企業開発でもよく使われています。
2. FlutterにBlocパッケージを導入しよう
BlocパターンをFlutterで使うには、公式のflutter_blocパッケージを導入します。
pubspec.yamlに以下を追加してください。
dependencies:
flutter:
sdk: flutter
flutter_bloc: ^8.1.3
その後、ターミナルでflutter pub getを実行してインストールします。
3. Blocの構成要素を理解しよう(Event・State・Bloc)
Blocでは、以下の3つの要素が基本です。
- Event(イベント):ユーザーの操作など、アクションの発生を表す
- State(状態):画面に表示するデータや状態を表す
- Bloc(ロジック):Eventを受け取り、Stateを更新するビジネスロジック
これらをクラスで定義し、UIと連携させることで、状態の変化に強いアプリが作れます。
Flutterを「実務レベル」で使えるようになりたい人や、 iPhone / Android両対応アプリ開発の流れをまとめて学びたい人には、 定番の実践書がこちらです。
Flutter実践開発をAmazonで見る※ Amazon広告リンク
4. FlutterでカウンターアプリをBlocで作ってみよう
ここでは、最もシンプルなカウンターアプリをBlocパターンで作成してみましょう。
まずはイベントクラスと状態クラスを定義します。
abstract class CounterEvent {}
class Increment extends CounterEvent {}
class CounterState {
final int count;
CounterState(this.count);
}
次にBloc本体を定義します。
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterState(0)) {
on<Increment>((event, emit) {
emit(CounterState(state.count + 1));
});
}
}
最後にUI側でBlocを使う部分を作成します。
class CounterScreen extends StatelessWidget {
const CounterScreen({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => CounterBloc(),
child: Scaffold(
appBar: AppBar(title: const Text('Blocカウンター')),
body: BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) {
return Center(
child: Text('カウント: ${state.count}'),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () => context.read<CounterBloc>().add(Increment()),
child: const Icon(Icons.add),
),
),
);
}
}
Blocパターンを使えば、UIと状態管理のコードを分離できるため、再利用や保守がしやすくなります。
5. BlocBuilderとBlocProviderの役割とは?
Blocパターンで使う2つの重要なウィジェットがあります。
- BlocProvider:Blocをアプリ全体または一部に提供する
- BlocBuilder:Blocの状態の変化に応じてUIを再構築する
BlocProviderはウィジェットツリーの上位でBlocを生成し、子ウィジェットで使えるようにします。
BlocBuilderは状態の変化に応じてUIを動的に変化させます。
6. Blocパターンを使うメリットと実践での活用例
Blocパターンは、以下のような場面で特に効果を発揮します。
- 複数の画面で共通の状態を扱いたいとき
- 非同期処理(API通信など)をUIに反映したいとき
- イベントドリブンで画面遷移やバリデーションを管理したいとき
また、Blocパターンはテストコードが書きやすく、業務アプリや大規模開発にも適しています。
7. BlocパターンとCubitの違いとは?
BlocパッケージにはCubitという軽量版も用意されています。
Blocは「イベント→状態→UI更新」という一連の流れがあるのに対し、Cubitは状態を直接操作します。
ロジックが複雑でない場面では、Cubitを使うことでコードがよりシンプルになります。まずはBlocで構造を理解してから、必要に応じてCubitを選ぶと良いでしょう。
まとめ
FlutterのBlocパターンで学んだ状態管理の考え方
この記事では、Flutterにおける代表的な状態管理手法であるBlocパターンについて、 基本概念から導入方法、実際のサンプルコードまでを通して解説してきました。 Blocパターンの最大の特徴は、画面表示を担当するUIと、アプリの振る舞いを決める ビジネスロジックを明確に分離できる点にあります。 これにより、コードの見通しが良くなり、機能追加や修正が発生しても影響範囲を 最小限に抑えることができます。
Flutterアプリでは、ユーザー操作や通信結果によって画面の状態が頻繁に変化します。 Blocパターンでは、その変化を「Event」「State」「Bloc」という三つの要素で整理します。 ユーザーの操作はイベントとしてBlocに送られ、Blocがその内容を判断して新しい状態を生成し、 その状態をUIが受け取って画面を更新します。 この流れを理解することで、状態管理が属人的にならず、誰が見ても分かりやすい構造になります。
Blocパターンが初心者にも役立つ理由
一見するとBlocパターンはクラスの数が多く、初心者には難しく感じられるかもしれません。 しかし、アプリの規模が少し大きくなるだけで、状態管理を整理する重要性を実感する場面は必ず訪れます。 画面とロジックを分けて考える習慣を早い段階で身につけておくことで、 Flutterの設計力そのものが大きく向上します。
特に業務アプリや長期間運用されるアプリでは、 状態の流れが分かりやすい設計が求められます。 Blocパターンはテストとの相性も良く、 ロジック部分をUIから切り離して検証できる点も大きな強みです。 初心者のうちからBlocの考え方に触れておくことで、 将来的により複雑なアプリ開発にもスムーズに対応できるようになります。
Blocの流れを整理する簡単なサンプル
// イベント
abstract class SampleEvent {}
class LoadData extends SampleEvent {}
// 状態
class SampleState {
final String message;
SampleState(this.message);
}
// Bloc
class SampleBloc extends Bloc<SampleEvent, SampleState> {
SampleBloc() : super(SampleState('初期状態')) {
on<LoadData>((event, emit) {
emit(SampleState('データを読み込みました'));
});
}
}
このサンプルでは、「イベントを受け取って状態を更新する」というBlocパターンの基本的な流れを示しています。 UI側ではこの状態を受け取り、表示内容を切り替えるだけでよいため、 ロジックを意識せずに画面設計に集中できます。 小さなサンプルでも、この構造を理解しておくことが大切です。
BlocとCubitを使い分ける意識を持とう
記事の後半で紹介したCubitは、Blocパターンをよりシンプルにした仕組みです。 イベントを定義せず、状態を直接変更できるため、 ロジックが単純な画面ではCubitの方が読みやすくなることもあります。 一方で、処理の流れを明確にしたい場合や、 イベント単位で状態遷移を管理したい場合はBlocが向いています。
どちらが正解というわけではなく、 アプリの規模や複雑さに応じて使い分けることが重要です。 まずはBlocパターンで基本構造を理解し、 慣れてきたらCubitも選択肢に入れるという流れがおすすめです。
生徒
「Blocって難しそうだと思っていましたが、 イベントと状態を分けて考えると意外と整理しやすいですね。」
先生
「その気づきはとても大切ですね。 状態管理を仕組みとして理解できるようになると、 Flutter開発が一気に楽になります。」
生徒
「画面のコードがすっきりするのも分かりました。 ロジックを別に書けるのは安心感があります。」
先生
「その通りです。最初は小さなアプリでも、 Blocの構造を意識して書く練習を続けてみましょう。」