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

Immer:イミュータブルデータの実践

Immer によるイミュータブルデータの実践について、多くの開発者は 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' }
  ))
)

このパターンは大規模プロジェクトで非常に実用的であり、保守コストを大幅に削減できる。

まとめ ​

  • チームでの協業では、規約とドキュメントが技術そのものよりも重要だ
  • コミュニティの動向を注視し、技術的なソリューションには継続的な反復が必要だ
  • 新しい技術を使うためだけに新しい技術を使うべきではない
  • コードサンプルは参考用に過ぎず、ビジネスの場面に応じた調整が必要だ

MIT Licensed