3
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?

状態管理とRx:UI状態・データフローの同期的表現

Posted at

概要

UIアプリケーションの複雑性は、状態の数・変化の頻度・依存関係によって爆発する。
状態管理ライブラリ(Redux, Vuex, Recoilなど)が人気を博したのは、状態を構造化し制御可能にしたからである。

一方で、Rxは状態そのものを**「ストリームとして扱う」**という別アプローチを提供する。
本稿では、Rx的な状態管理とは何か?どうやってUIやデータと統合するのか?を構造的に明らかにする。


1. 状態 = ストリームの現在値

Rxでは状態を「ある時点における値」とは見なさない。
**“時間と共に変化するストリームの一断面”**として扱う。

状態とは、「過去→現在→未来」へと連続的に変化し続ける値の履歴である。


2. BehaviorSubject:状態の最小単位

import { BehaviorSubject } from 'rxjs'

const count$ = new BehaviorSubject(0)

count$.next(1)
count$.next(2)

count$.subscribe((v) => console.log(v)) // 出力:2(最新値)
  • BehaviorSubject最新値を常に保持し、購読者には即座に通知
  • Reduxなどにおける store.getState() に相当

3. UI状態をストリームで管理する構造

const isLoading$ = new BehaviorSubject(false)
const data$ = new BehaviorSubject<any[]>([])
const error$ = new BehaviorSubject<Error | null>(null)

function fetchData() {
  isLoading$.next(true)
  ajax.getJSON('/api/items')
    .subscribe({
      next: (result) => data$.next(result),
      error: (e) => error$.next(e),
      complete: () => isLoading$.next(false)
    })
}

→ 複数の状態が同じ構造=ストリームで管理され、購読者に即時伝播


4. combineLatest:状態の同期合成

combineLatest([data$, isLoading$, error$])
  .subscribe(([data, loading, error]) => {
    render({ data, loading, error })
  })
  • 複数状態の「現在値」を組み合わせて1つの描画関数にまとめる
  • 再描画ロジックの副作用依存を削除

5. 状態の流れを関数型で構築する

search$
  .pipe(
    debounceTime(300),
    tap(() => isLoading$.next(true)),
    switchMap(keyword => fetch(keyword)),
    tap(() => isLoading$.next(false))
  )
  .subscribe((result) => data$.next(result))

→ 処理と状態更新が一貫した流れとして構築されている
→ **「副作用が制御された非同期UI」**を実現可能


6. UIコンポーネントとの接続戦略

✅ Reactでの例(rxjs-hooks)

const data = useObservable(() => data$, [])
const loading = useObservable(() => isLoading$, [])

useEffect など不要。状態とUIを1:1にマッピング


✅ Vueでの例(setup内)

const data = ref([])
data$.subscribe(v => data.value = v)

→ Composition APIとも相性が良く、Rxによる状態管理を自然に統合可能


よくある誤解と対策

❌ 状態管理ライブラリをRxで置き換えるのは過剰

→ ✅ 小規模であればその通り。ただし、非同期の依存性や状態のスコープが複雑な場合は圧倒的に強い


❌ Subjectが乱立して管理が煩雑になる

→ ✅ 設計ミス。状態は1方向に流れるようストリーム構造を整えることで解消可能


❌ テストが難しい

→ ✅ 実は逆。ストリームに対して値を発行して期待結果を確認するだけで済む(マーブルテストも可能)


結語

UI状態をRxで管理するということは、
状態を“断片化された変数”ではなく、“流れ続ける一貫したストリーム”として再定義することである。

  • 複数状態を合成し
  • 非同期を中断・統合・分岐し
  • 副作用と描画を明示的に制御する

リアクティブな状態管理とは、
“制御不能な変化のカオスを、秩序あるデータストリームへ変換する設計戦略である。”

3
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
3
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?