欢迎光临殡葬白事网
详情描述

1. 基础Store实现

// store/counterStore.ts
import { create } from 'zustand'
import { persist, createJSONStorage } from 'zustand/middleware'

// 定义状态类型
interface CounterState {
  count: number
  name: string
  increment: () => void
  decrement: () => void
  incrementBy: (amount: number) => void
  reset: () => void
  setName: (name: string) => void
}

// 创建store(带持久化)
export const useCounterStore = create<CounterState>()(
  persist(
    (set, get) => ({
      count: 0,
      name: '初始用户',

      increment: () => 
        set((state) => ({ count: state.count + 1 })),

      decrement: () => 
        set((state) => ({ count: state.count - 1 })),

      incrementBy: (amount) => 
        set((state) => ({ count: state.count + amount })),

      reset: () => 
        set({ count: 0 }),

      setName: (name) => 
        set({ name }),
    }),
    {
      name: 'counter-storage', // localStorage的key
      storage: createJSONStorage(() => localStorage),
      partialize: (state) => ({ 
        count: state.count,
        name: state.name 
      }), // 选择性持久化
    }
  )
)

2. 更复杂的Todo示例

// store/todoStore.ts
import { create } from 'zustand'
import { devtools } from 'zustand/middleware'

export interface Todo {
  id: string
  text: string
  completed: boolean
  createdAt: Date
}

interface TodoState {
  todos: Todo[]
  filter: 'all' | 'active' | 'completed'
  addTodo: (text: string) => void
  toggleTodo: (id: string) => void
  deleteTodo: (id: string) => void
  updateTodo: (id: string, text: string) => void
  clearCompleted: () => void
  setFilter: (filter: 'all' | 'active' | 'completed') => void
  getCompletedTodos: () => Todo[]
  getActiveTodos: () => Todo[]
}

export const useTodoStore = create<TodoState>()(
  devtools(
    (set, get) => ({
      todos: [],
      filter: 'all',

      addTodo: (text) =>
        set((state) => ({
          todos: [
            ...state.todos,
            {
              id: Date.now().toString(),
              text,
              completed: false,
              createdAt: new Date(),
            },
          ],
        })),

      toggleTodo: (id) =>
        set((state) => ({
          todos: state.todos.map((todo) =>
            todo.id === id
              ? { ...todo, completed: !todo.completed }
              : todo
          ),
        })),

      deleteTodo: (id) =>
        set((state) => ({
          todos: state.todos.filter((todo) => todo.id !== id),
        })),

      updateTodo: (id, text) =>
        set((state) => ({
          todos: state.todos.map((todo) =>
            todo.id === id ? { ...todo, text } : todo
          ),
        })),

      clearCompleted: () =>
        set((state) => ({
          todos: state.todos.filter((todo) => !todo.completed),
        })),

      setFilter: (filter) => set({ filter }),

      getCompletedTodos: () => 
        get().todos.filter((todo) => todo.completed),

      getActiveTodos: () => 
        get().todos.filter((todo) => !todo.completed),
    }),
    { name: 'TodoStore' }
  )
)

3. 异步操作示例

// store/userStore.ts
import { create } from 'zustand'

interface User {
  id: number
  name: string
  email: string
}

interface UserState {
  user: User | null
  loading: boolean
  error: string | null
  fetchUser: (userId: number) => Promise<void>
  updateUser: (userData: Partial<User>) => Promise<void>
}

export const useUserStore = create<UserState>((set, get) => ({
  user: null,
  loading: false,
  error: null,

  fetchUser: async (userId) => {
    set({ loading: true, error: null })

    try {
      const response = await fetch(
        `https://jsonplaceholder.typicode.com/users/${userId}`
      )

      if (!response.ok) {
        throw new Error('用户获取失败')
      }

      const userData = await response.json()
      set({ user: userData, loading: false })

    } catch (error) {
      set({ 
        error: error instanceof Error ? error.message : '未知错误',
        loading: false 
      })
    }
  },

  updateUser: async (userData) => {
    const { user } = get()
    if (!user) return

    set({ loading: true })

    try {
      // 模拟API请求
      await new Promise(resolve => setTimeout(resolve, 500))

      set((state) => ({
        user: { ...state.user!, ...userData },
        loading: false,
      }))

    } catch (error) {
      set({ 
        error: error instanceof Error ? error.message : '未知错误',
        loading: false 
      })
    }
  },
}))

4. React组件中使用

// components/Counter.tsx
import React from 'react'
import { useCounterStore } from '../store/counterStore'
import { shallow } from 'zustand/shallow'

// 使用selector优化性能(避免不必要的重渲染)
export const Counter = () => {
  const { count, increment, decrement, reset } = useCounterStore(
    (state) => ({
      count: state.count,
      increment: state.increment,
      decrement: state.decrement,
      reset: state.reset,
    }),
    shallow // 浅比较,避免每次创建新对象导致的重复渲染
  )

  return (
    <div>
      <h1>计数: {count}</h1>
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
      <button onClick={reset}>重置</button>
    </div>
  )
}
// components/TodoList.tsx
import React, { useState } from 'react'
import { useTodoStore } from '../store/todoStore'

export const TodoList = () => {
  const [input, setInput] = useState('')
  const {
    todos,
    filter,
    addTodo,
    toggleTodo,
    deleteTodo,
    clearCompleted,
    setFilter,
    getActiveTodos,
    getCompletedTodos,
  } = useTodoStore()

  const displayTodos = filter === 'all' 
    ? todos 
    : filter === 'active' 
      ? getActiveTodos()
      : getCompletedTodos()

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    if (input.trim()) {
      addTodo(input.trim())
      setInput('')
    }
  }

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="添加新任务..."
        />
        <button type="submit">添加</button>
      </form>

      <div>
        <button onClick={() => setFilter('all')}>全部</button>
        <button onClick={() => setFilter('active')}>未完成</button>
        <button onClick={() => setFilter('completed')}>已完成</button>
      </div>

      <ul>
        {displayTodos.map((todo) => (
          <li key={todo.id}>
            <input
              type="checkbox"
              checked={todo.completed}
              onChange={() => toggleTodo(todo.id)}
            />
            <span style={{
              textDecoration: todo.completed ? 'line-through' : 'none'
            }}>
              {todo.text}
            </span>
            <button onClick={() => deleteTodo(todo.id)}>删除</button>
          </li>
        ))}
      </ul>

      <button onClick={clearCompleted}>
        清除已完成 ({getCompletedTodos().length})
      </button>
    </div>
  )
}

5. 跨Store通信

// store/index.ts
import { create } from 'zustand'
import { counterStore } from './counterStore'
import { todoStore } from './todoStore'

// 组合多个store
const useCombinedStore = create((set, get) => ({
  ...counterStore(set, get),
  ...todoStore(set, get),
}))

6. TypeScript类型安全配置

// store/types.ts
// 集中管理类型定义
export type { CounterState } from './counterStore'
export type { Todo, TodoState } from './todoStore'
export type { User, UserState } from './userStore'

7. 测试示例

// __tests__/counterStore.test.ts
import { act, renderHook } from '@testing-library/react'
import { useCounterStore } from '../store/counterStore'

describe('CounterStore', () => {
  beforeEach(() => {
    const { result } = renderHook(() => useCounterStore())
    act(() => {
      result.current.reset()
    })
  })

  it('should increment counter', () => {
    const { result } = renderHook(() => useCounterStore())

    act(() => {
      result.current.increment()
    })

    expect(result.current.count).toBe(1)
  })

  it('should decrement counter', () => {
    const { result } = renderHook(() => useCounterStore())

    act(() => {
      result.current.increment()
      result.current.decrement()
    })

    expect(result.current.count).toBe(0)
  })
})

主要优点

简洁直观:API设计简单,学习成本低 类型安全:完整的TypeScript支持 性能优化:自动去重渲染,支持selector模式 中间件支持:持久化、DevTools、日志等 无样板代码:不需要Provider包裹 灵活的更新:支持函数式和对象式更新

最佳实践

将store拆分为逻辑模块 使用selector优化性能 合理使用中间件 类型定义集中管理 异步操作统一错误处理 使用DevTools进行调试

这个示例展示了Zustand的核心功能,你可以根据实际需求进行调整和扩展。

相关帖子
从法律角度看,高空抛物全楼DNA检测的费用分摊依据是什么?
从法律角度看,高空抛物全楼DNA检测的费用分摊依据是什么?
社保补缴的办理流程是怎样的,是否支持线上申请和查询进度?
社保补缴的办理流程是怎样的,是否支持线上申请和查询进度?
园林造景艺术:不同叶形、叶色树木在景观设计中的搭配原则
园林造景艺术:不同叶形、叶色树木在景观设计中的搭配原则
智能家居普及,如何防止家庭隐私数据被泄露?
智能家居普及,如何防止家庭隐私数据被泄露?
昼夜温差与甜度关系:高原地区甜椒糖分积累的特殊机制
昼夜温差与甜度关系:高原地区甜椒糖分积累的特殊机制
沈阳市殡葬服务热线电话%丧事拍摄,白事丧事服务
沈阳市殡葬服务热线电话%丧事拍摄,白事丧事服务
拉萨市丧葬悼念会#殡葬服务办理,全天在线
拉萨市丧葬悼念会#殡葬服务办理,全天在线
订阅制模式在哪些类型的消费品或服务中,对消费者相对更有利?
订阅制模式在哪些类型的消费品或服务中,对消费者相对更有利?
除了庆祝,成人礼如何成为一次关于未来财务规划意识的启蒙时刻?
除了庆祝,成人礼如何成为一次关于未来财务规划意识的启蒙时刻?
达州市殡葬服务价格%灵堂超度,丧葬一条龙价格
达州市殡葬服务价格%灵堂超度,丧葬一条龙价格
自带酒水与餐厅提供的酒水服务,在体验上有哪些具体的区别与特点?
自带酒水与餐厅提供的酒水服务,在体验上有哪些具体的区别与特点?
办理押车贷款注意事项,确认提前还款是否收违约金比例
办理押车贷款注意事项,确认提前还款是否收违约金比例
如果偶然发现一枚生锈的古钱,正确的清理和保存方法应该是怎样的步骤?
如果偶然发现一枚生锈的古钱,正确的清理和保存方法应该是怎样的步骤?
公积金缴存多久,才有贷款资格?
公积金缴存多久,才有贷款资格?
大货车贷款怎么办理?新手必看的全流程攻略指南详解
大货车贷款怎么办理?新手必看的全流程攻略指南详解
非本地户籍人员在工作或生活地申请法律援助补贴有哪些注意事项?
非本地户籍人员在工作或生活地申请法律援助补贴有哪些注意事项?
线上线下办理过桥垫资对比,两种渠道操作步骤、优缺点分析
线上线下办理过桥垫资对比,两种渠道操作步骤、优缺点分析
2026年,家庭物联网冰箱如何自动监控并预警食品的剩余保质期?
2026年,家庭物联网冰箱如何自动监控并预警食品的剩余保质期?
红河殡葬一条龙公司电话%丧葬拍摄,殡仪一条龙服务
红河殡葬一条龙公司电话%丧葬拍摄,殡仪一条龙服务
常德市丧葬拍摄#殡葬一条龙公司,专业高效
常德市丧葬拍摄#殡葬一条龙公司,专业高效