mcpField
F
flutter-bloc

flutter-bloc

github.com/dhruvanbhalara開発30255 回インストール8 週間前に更新
リポジトリ

flutter-bloc について

Flutter で状態管理を実装する開発者向けの BLoC スキルです。不変のイベントと状態、非同期処理、UI の責務、依存性注入、ルーティングの規約を定めています。

主な機能

  1. 01sealed な不変イベントと状態
  2. 02読み込みから結果への非同期フロー
  3. 03BLoC ウィジェットの使用指針
  4. 04依存性注入の規約
  5. 05ルーティングと Provider の規則
  6. 06機能ごとのディレクトリ構成

活用シーン

  1. 01Flutter BLoC 機能の実装開始
  2. 02非同期状態遷移の確認
  3. 03UI とビジネスロジックの分離
  4. 04ルーティングと BLoC Provider の整理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dhruvanbhalara/skills --skill flutter-bloc

インストール後、Claude Code で/flutter-blocを入力して読み込まれたか確認します。

詳細

BLoC パターン

  • シールドされた State と Event: State と Event の両方に常に sealed class を使用し、UI の網羅的な処理とコンパイル時の安全性を確保します。
  • 不変性: すべての State、Event、ドメインエンティティは不変でなければなりません(final と Equatable または freezed を使用)。
  • 公式 BLoC の Part-Part Of パターン: すべての _bloc.dart ファイルは、対応する _event.dart と _state.dart ファイルを part ディレクティブで必ず含める必要があります。各 event/state ファイルには、bloc ファイルを指し示す part of ディレクティブが必ず必要です。これにより、単一のライブラリスコープと共有されたプライベートメンバーが保証されます。
    // auth_bloc.dart
    part 'auth_event.dart';
    part 'auth_state.dart';
    
    class AuthBloc extends Bloc<AuthEvent, AuthState> { ... }
    
    // auth_event.dart
    part of 'auth_bloc.dart';
    
    // auth_state.dart
    part of 'auth_bloc.dart';
    
  • 必須のディレクトリ構造: すべての BLoC 機能セットは、bloc/ フォルダー内の独自のサブディレクトリに必ず配置する必要があります。フラットな bloc/ ディレクトリは厳格に禁止します。
    presentation/bloc/
    └── <bloc_name>/
        ├── <bloc_name>_bloc.dart
        ├── <bloc_name>_event.dart
        └── <bloc_name>_state.dart
    
  • ローディング State の義務: 非同期処理の前に必ず Loading を emit し、その後 Success または Error を emit してください。ローディング State を決して省略しないでください。
  • 並行処理: デバウンス(検索)やスロットリング(ボタン)が必要なイベントには、transformers(例: restartable()、droppable())を使用します。
  • ゼロロジック UI: ウィジェットにビジネスロジック、オーケストレーションロジック、外部サービスへの直接呼び出しを含めてはなりません。イベントを dispatch し、BLoC の State に基づいて UI を構築するだけにしてください。

BLoC ウィジェットの使用方法

  • State に基づくローカルな UI 再構築には BlocBuilder
  • 副作用(ナビゲーション、スナックバー、ダイアログ)には BlocListener
  • 再構築と副作用の両方が必要な場合は BlocConsumer
  • イベントの dispatch には context.read<Bloc>().add(Event())
  • リアクティブな再構築には context.watch<Bloc>().state(build() 内のみ)

ワークフロー: State 管理の実装

BLoC を追加または更新する際は、以下の順序でワークフローに従ってください。チェックリストをコピーして進捗を追跡してください。

タスクの進捗
  • ステップ 1: Event と State を定義する。 正しい props を持つ Equatable または freezed を使用していることを確認してください。
  • ステップ 2: 非同期操作を実装する。 すべての非同期処理が Loading → Success/Error パターンに従っていることを確認してください。
  • ステップ 3: UI をリファクタリングする。 UI ウィジェットにオーケストレーションやビジネスロジックが存在しないことを確認してください。ウィジェットはイベントを dispatch するだけにしてください。
  • ステップ 4: データソースを検証する。 DataSources の外に SDK/API 呼び出しが存在しないことを確認してください。
  • ステップ 5: デザイントークンをレビューする。 ハードコードされた色、スペーシング、タイポグラフィが一切使用されていないことを確認してください。
  • ステップ 6: コードをフォーマットする。 コードが dart format でフォーマットされていることを確認してください。

依存性注入

  • 依存性注入とサービスロケーターには injectable を使用します
  • 標準化された注入:
    • 画面ごとに新しいインスタンスを保証するため、画面固有の BLoC には @injectable を使用します。
    • グローバルまたは共有の BLoC(例: AuthBloc、ThemeBloc、SettingsBloc、PasswordBloc)には @lazySingleton を使用します。
  • BLoC を機能ごとに論理的に整理し、関心の厳格な分離を確保します

ナビゲーションとルーティング

  • 動的ルート: GoRouter の設定でハードコードされたルート文字列を厳格に禁止します。AppRoutes の静的定数を使用してください。
  • 集中化された BLoC: 複数の画面で共有される場合、または機能ブランチ内で共有される場合、BLoC プロバイダーは app_router.dart の ShellRoute または BlocProvider を介して注入する必要があります。
  • ローカルプロバイダーの禁止: BLoC が機能セットで必要とされる場合、個々の画面の build() メソッドで BlocProvider を使用することは避けてください。
  • プリミティブなルート引数: 複雑なオブジェクト(BLoC、ChangeNotifier、エンティティインスタンス)をルート引数として渡すことを厳格に禁止します。プリミティブな ID/Key のみを渡し、Repository または Bloc の注入を使用して遷移先の画面でデータを取得してください。

コメント