🎯

rxdart BehaviorSubjectを使ってみた

に公開

BehaviorSubject in RxDart

https://pub.dev/packages/rxdart

BehaviorSubjectは、RxDartで提供される特殊なSubjectの一つです。通常のStreamと異なり、最新の値を保持し、新しい購読者に対して即座にその値を提供する機能を持っています。

https://pub.dev/documentation/rxdart/latest/rx/BehaviorSubject-class.html

基本的な使い方

final subject = BehaviorSubject<int>();

subject.add(1);
subject.add(2);
subject.add(3);

subject.stream.listen(print); // 3を出力
subject.stream.listen(print); // 3を出力
subject.stream.listen(print); // 3を出力

初期値を設定する場合:

final subject = BehaviorSubject<int>.seeded(1);

subject.stream.listen(print); // 1を出力
subject.stream.listen(print); // 1を出力
subject.stream.listen(print); // 1を出力

実践的な例:天気予報アプリ

以下は、天気予報アプリでBehaviorSubjectを使用する例です:

import 'package:rxdart/rxdart.dart';

void main() {
  // 天気予報の更新を模擬したBehaviorSubject
  final weatherSubject = BehaviorSubject<String>.seeded('晴れ');
  
  // 最初の購読者(天気アプリのホーム画面と仮定)
  print('ホーム画面を開く:');
  weatherSubject.stream.listen(
    (weather) => print('ホーム画面の表示: $weather'),
  );
  
  // 天気が変化
  print('\n天気が変化:');
  weatherSubject.add('雨');
  
  // 新しい購読者(通知画面と仮定)が後から参加
  print('\n通知画面を開く:');
  weatherSubject.stream.listen(
    (weather) => print('通知画面の表示: $weather'),
  );
  
  // さらに天気が変化
  print('\n天気が再度変化:');
  weatherSubject.add('曇り');
  
  // 3番目の購読者(ウィジェット画面と仮定)
  print('\n通知画面を開く:');
  weatherSubject.stream.listen(
    (weather) => print('ウィジェット画面の表示: $weather'),
  );

  // 最後にSubjectをクローズ
  weatherSubject.close();
}

実行結果:

ホーム画面を開く:

天気が変化:

通知画面を開く:

天気が再度変化:

ウィジェット画面を開く:
ホーム画面の表示: 晴れ
ホーム画面の表示: 雨
通知画面の表示: 雨
通知画面の表示: 曇り
ウィジェット画面の表示: 曇り
ホーム画面の表示: 曇り

BehaviorSubjectの主な特徴

  1. 最新値の保持

    • 最後に発行された値を保持します
    • 新しい購読者は購読開始時に最新の値を即座に受け取ります
    • .seeded()で初期値を設定できます
  2. Hot Observable

    • 購読者の有無に関わらず値を発行できます
    • すべての購読者が同じ値を受け取ります
  3. 値の更新と通知

    • add()メソッドで新しい値を追加すると、すべての購読者に通知されます
    • すべての購読者が同じ最新の値を受け取ります

一般的な使用例

BehaviorSubjectは以下のようなケースで特に有用です:

  • ユーザー設定の管理

    • アプリのテーマ設定
    • 言語設定
    • 表示設定
  • 認証状態の管理

    • ログイン状態
    • ユーザープロファイル情報
  • フォームの状態管理

    • 入力値の管理
    • バリデーション状態
  • アプリの状態管理

    • 現在の画面状態
    • データの読み込み状態

注意点

  1. メモリ管理のため、使用が終わったらかならずclose()を呼び出す
  2. 初期値が必要な場合は.seeded()を使用する
  3. 複数の購読者がいる場合、すべての購読者が同じ値を受け取ることを考慮する

Discussion