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