Skip to content
⚠️ This article was written in 2020. Some content may be outdated.

XState有限状態機械のフロントエンドへの応用

XState 有限状態機械のフロントエンド応用について、多くの開発者は API 呼び出しの層にとどまっています。本稿では本番環境の観点から、実際に直面する問題とその解決策を議論します。

基本原理 ​

これを踏まえて、さらに最適化できます:

javascript
import { create } from 'zustand'
import { persist, devtools } from 'zustand/middleware'

const useStore = create(
  devtools(persist(
    (set, get) => ({
      user: null,
      theme: 'light',
      notifications: [],
      setUser: (user) => set({ user }),
      toggleTheme: () => set(s => ({
        theme: s.theme === 'light' ? 'dark' : 'light'
      })),
      unreadCount: () => get().notifications.filter(n => !n.read).length
    }),
    { name: 'app-store' }
  ))
)

このパターンは大規模なプロジェクトで非常に実用的で、保守コストを大幅に下げられます。

高度な機能 ​

実際のプロジェクトでは、もう少し複雑に使うことになります:

javascript
import { create } from 'zustand'
import { persist, devtools } from 'zustand/middleware'

const useStore = create(
  devtools(persist(
    (set, get) => ({
      user: null,
      theme: 'light',
      notifications: [],
      setUser: (user) => set({ user }),
      toggleTheme: () => set(s => ({
        theme: s.theme === 'light' ? 'dark' : 'light'
      })),
      unreadCount: () => get().notifications.filter(n => !n.read).length
    }),
    { name: 'app-store' }
  ))
)

このアプローチにより、コードのテスト容易性と拡張性の両方が向上します。

プロジェクト実践 ​

以下は完全なサンプルです:

javascript
import { create } from 'zustand'
import { persist, devtools } from 'zustand/middleware'

const useStore = create(
  devtools(persist(
    (set, get) => ({
      user: null,
      theme: 'light',
      notifications: [],
      setUser: (user) => set({ user }),
      toggleTheme: () => set(s => ({
        theme: s.theme === 'light' ? 'dark' : 'light'
      })),
      unreadCount: () => get().notifications.filter(n => !n.read).length
    }),
    { name: 'app-store' }
  ))
)

境界条件の処理に注意してください。これは本番環境では極めて重要です。

ベストプラクティス ​

鍵となるのは、コアロジックを理解することです:

javascript
import { create } from 'zustand'
import { persist, devtools } from 'zustand/middleware'

const useStore = create(
  devtools(persist(
    (set, get) => ({
      user: null,
      theme: 'light',
      notifications: [],
      setUser: (user) => set({ user }),
      toggleTheme: () => set(s => ({
        theme: s.theme === 'light' ? 'dark' : 'light'
      })),
      unreadCount: () => get().notifications.filter(n => !n.read).length
    }),
    { name: 'app-store' }
  ))
)

パフォーマンス最適化は具体的なシナリオと組み合わせる必要があり、すべてのケースで過度な最適化が必要なわけではありません。

ハマりやすい注意点 ​

次の方法で改善できます:

javascript
import { create } from 'zustand'
import { persist, devtools } from 'zustand/middleware'

const useStore = create(
  devtools(persist(
    (set, get) => ({
      user: null,
      theme: 'light',
      notifications: [],
      setUser: (user) => set({ user }),
      toggleTheme: () => set(s => ({
        theme: s.theme === 'light' ? 'dark' : 'light'
      })),
      unreadCount: () => get().notifications.filter(n => !n.read).length
    }),
    { name: 'app-store' }
  ))
)

このアプローチは本番環境で半年以上安定して稼働しており、実際に検証されています。

まとめ ​

  • XState 有限状態機械のフロントエンド応用は銀の弾丸ではなく、プロジェクトの規模と技術スタックに応じて選ぶ必要があります
  • API を覚えるよりも、基礎となる原理を理解するほうが重要です
  • 本番環境で使う前に、必ず互換性の検証を行ってください
  • チームでの協業において、約束事とドキュメントは技術そのものよりも重要です

MIT Licensed