使用 Zustand 在 React 中管理状态

Zustand 是一个轻量级的 React 状态管理库,它提供了简单、灵活的方式来管理应用状态。下面是如何使用 Zustand 的基本指南。

安装 Zustand

首先,安装 zustand 包:

npm install zustand

或
yarn add zustand

创建 Store

创建一个 store 来管理你的状态:

// store.js
import { create } from 'zustand'

const useStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  decrement: () => set((state) => ({ count: state.count - 1 })),
  reset: () => set({ count: 0 }),
}))

在组件中使用 Store

基本用法

import { useStore } from './store'

function Counter() {
  const count = useStore((state) => state.count)
  const increment = useStore((state) => state.increment)
  const decrement = useStore((state) => state.decrement)
  const reset = useStore((state) => state.reset)

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
      <button onClick={reset}>Reset</button>
    </div>
  )
}

优化性能

为了避免不必要的重新渲染,可以单独选择需要的状态:

function Counter() {
  const { count, increment } = useStore((state) => ({
    count: state.count,
    increment: state.increment,
  }))

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={increment}>+</button>
    </div>
  )
}

或者使用 selector 函数:

function Counter() {
  const count = useStore((state) => state.count)
  const increment = useStore((state) => state.increment)

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={increment}>+</button>
    </div>
  )
}

异步操作

Zustand 也支持异步操作:

const useStore = create((set) => ({
  data: null,
  loading: false,
  error: null,
  fetchData: async () => {
    set({ loading: true })
    try {
      const response = await fetch('https://api.example.com/data')
      const data = await response.json()
      set({ data, loading: false })
    } catch (error) {
      set({ error, loading: false })
    }
  },
}))

在组件外使用 Store

你可以在 React 组件外使用 store:

// 在任何地方获取状态
const currentCount = useStore.getState().count

// 在任何地方更新状态
useStore.setState({ count: 10 })

// 订阅状态变化
const unsubscribe = useStore.subscribe((newState, prevState) => {
  console.log('状态变化:', prevState, '->', newState)
})

// 取消订阅
unsubscribe()

结合中间件

Zustand 支持中间件,例如持久化存储:

import { persist } from 'zustand/middleware'

const useStore = create(
  persist(
    (set) => ({
      count: 0,
      increment: () => set((state) => ({ count: state.count + 1 })),
    }),
    {
      name: 'count-storage', // 本地存储的键名
    }
  )
)

TypeScript 支持

Zustand 完全支持 TypeScript:

interface StoreState {
  count: number
  increment: () => void
  decrement: () => void
}

const useStore = create<StoreState>((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  decrement: () => set((state) => ({ count: state.count - 1 })),
}))

Zustand 是一个简单但功能强大的状态管理解决方案,特别适合中小型应用或需要轻量级状态管理的场景。