zustand-pro
v1.0.9
Published
zustand-pro is a simple and efficient state management solution using Zustand
Maintainers
Readme
zustand-pro
A concise and efficient state management solution based on Zustand, providing complete TypeScript type inference and modular design.
基于 Zustand 的简洁、高效状态管理方案,提供完整的 TypeScript 类型推导和模块化设计。
✨ Features
✨ 核心特性
- 🎯 Full Type Inference - TypeScript automatically infers state, actions, and computed types
- 📦 Modular Design - One
createStorecreates a complete store - ⚡ Immer Support - Direct deep object mutation
- 🧮 Computed Properties - Supports both value and function forms
- 💾 Persistence - Supports selective persistence
- 🔍 Dev Logger - Track action calls with parameters
- 🪝 React Hooks - useStore, useAction, useCompute
- 🔄 Lifecycle - onMounted, watchAction, effect
- ⏳ Auto Loading - Automatic loading state for async actions
- 📡 State Listener - subscribe for state changes
- 🎯 完整类型推导 - TypeScript 自动推断 state、actions、computed 类型
- 📦 模块化设计 - 一个
createStore创建完整 store - ⚡ Immer 支持 - 深层对象直接修改
- 🧮 计算属性 - 支持值形式和函数形式
- 💾 持久化存储 - 支持选择性持久化
- 🔍 开发日志 - 追踪 action 调用及参数
- 🪝 React Hooks - useStore、useAction、useCompute
- 🔄 生命周期 - onMounted、watchAction、effect
- ⏳ 自动 Loading - 自动追踪异步 action 的 loading 状态
- 📡 状态监听 - subscribe 监听状态变化
📦 Installation
📦 安装
npm install zustand zustand-proRequirements: zustand >=4.5.0, React >=17.0.0
要求:zustand >=4.5.0,React >=17.0.0
🚀 Complete Example
🚀 完整示例
import { createStore } from 'zustand-pro'
// Create a complete Todo Store
// 创建一个完整的 Todo Store
const todoStore = createStore({
name: 'todos',
// Initial state
// 初始状态
state: {
todos: [] as Array<{ id: number; text: string; done: boolean }>,
filter: 'all' as 'all' | 'done' | 'pending',
},
// Computed properties (supports value and function forms)
// 计算属性(支持值形式和函数形式)
compute: get => ({
// Value form - returns computed value directly
// 值形式 - 直接返回计算值
totalCount: get().todos.length,
doneCount: get().todos.filter(t => t.done).length,
// Function form - with parameters
// 函数形式 - 带参数的计算函数
filteredTodos: (done?: boolean) => {
const { todos, filter } = get()
if (done !== undefined) return todos.filter(t => t.done === done)
if (filter === 'done') return todos.filter(t => t.done)
if (filter === 'pending') return todos.filter(t => !t.done)
return todos
},
}),
// Persistence config
// 持久化配置
persist: {
partialize: state => ({ todos: state.todos }), // Only persist todos / 仅持久化 todos
},
// Dev logger
// 开发日志
logger: true,
// Lifecycle: executed after store creation
// 生命周期:store 创建后执行
onMounted: store => {
console.log('Todo Store initialized')
// Can load initial data here / 可以在这里加载初始数据
},
// Listen to action calls
// 监听 action 调用
watchAction: {
clearTodos: (_params, actions, _store) => {
console.log('todos cleared')
},
},
// Listen to state property changes
// 监听状态属性变化
effect: {
filter: (newValue, oldValue, actions, _store) => {
console.log(`filter changed from ${oldValue} to ${newValue}`)
// Can trigger other operations here / 可以在这里触发其他操作
},
},
// Actions
// 操作函数
actions: (set, get, self) => {
const addTodo: (text: string) => set({
todos: [...get().todos, { id: Date.now(), text, done: false }],
})
const toggleTodo: (id: number) => set({
todos: get().todos.map(t => t.id === id ? { ...t, done: !t.done } : t),
})
const setFilter: (filter: 'all' | 'done' | 'pending') => set({ filter })
const clearTodos: () => set({ todos: [] })
const loadTodos = async () => {
const data = await fetch('/api/todos').then(r => r.json())
set({ todos: data })
}
// ... other actions / 其他操作
return {
addTodo,
toggleTodo,
setFilter,
clearTodos,
loadTodos
}
}
// Auto loading state for async actions
// 自动追踪异步 action 的 loading 状态
autoLoading: ['loadTodos'],
})
// Destructure exports for clean usage
// 解构导出,使用更简洁
export const {
useStore, useAction, useCompute,
getState, getAction, getCompute, subscribe
} = todoStore
// ========== Use in React / 在 React 中使用 ==========
function TodoApp() {
// Get state / 获取状态
const todos = useStore(s => s.todos)
// Get auto loading state (autoLoading generates this automatically)
// 获取自动 loading 状态(autoLoading 自动生成)
const loading = useStore(s => s.$loading?.loadTodos)
// Get actions / 获取 actions
const { addTodo, toggleTodo, setFilter, loadTodos } = useAction()
// Or use selector / 或使用 selector
const addTodoAction = useAction(a => a.addTodo)
// Get computed properties / 获取计算属性
const { totalCount, doneCount } = useCompute()
// Or use selector / 或使用 selector
const count = useCompute(c => c.totalCount)
const filtered = useCompute(c => c.filteredTodos(true))
return (
<div>
<span>Total: {totalCount} / Done: {doneCount}</span>
<button onClick={() => addTodo('New Task')}>Add</button>
<button onClick={() => setFilter('done')}>Filter Done</button>
<button onClick={() => loadTodos()}>Load Todos</button>
{loading && <span>Loading...</span>}
</div>
)
}
// ========== Use outside React / 在 React 外使用 ==========
// Get state / 获取状态
const state = getState()
const count = getState(s => s.todos.length)
// Get actions / 获取 actions
const actions = getAction()
const addTodo = getAction(a => a.addTodo)
// Get computed / 获取计算属性
const computed = getCompute()
const total = getCompute(c => c.totalCount)
// Subscribe to state changes / 监听状态变化
const unsubscribe = subscribe((state, prevState) => {
console.log('State changed:', state.todos.length)
})
unsubscribe() // Cancel subscription / 取消订阅
// Call action / 调用 action
actions.addTodo('Learn zustand-pro')
actions.setFilter('done')
// Async action with auto loading / 带 autoLoading 的异步 action
actions.loadTodos() // loading.loadTodos will auto toggle / loading.loadTodos 会自动切换🏆 Comparison
🏆 对比
| Feature | Zustand Native | zustand-pro | | ------------------- | --------------------- | ----------------------- | | Type Inference | Manual definition | ✅ Auto inference | | Computed Properties | Manual implementation | ✅ Built-in compute | | Modular Design | Scattered definitions | ✅ Unified config | | Actions Hook | None | ✅ useAction(selector) | | Computed Hook | None | ✅ useCompute(selector) | | Immer Integration | Manual config | ✅ One-line enable | | Action Logging | None | ✅ Call tracking | | Lifecycle | None | ✅ onMounted | | Action Listener | None | ✅ watchAction | | State Listener | None | ✅ effect | | Auto Loading | Manual management | ✅ Auto tracking |
| 特性 | Zustand 原生 | zustand-pro | | ------------- | ------------ | ----------------------- | | 类型推导 | 需手动定义 | ✅ 全自动推断 | | 计算属性 | 需手动实现 | ✅ 内置 compute | | 模块化 | 分散定义 | ✅ 统一配置 | | Actions Hook | 无 | ✅ useAction(selector) | | Computed Hook | 无 | ✅ useCompute(selector) | | Immer 集成 | 需手动配置 | ✅ 一键开启 | | 日志追踪 | 无 | ✅ action 调用日志 | | 生命周期 | 无 | ✅ onMounted | | Action 监听 | 无 | ✅ watchAction | | 状态监听 | 无 | ✅ effect | | 自动 Loading | 手动管理 | ✅ 自动追踪 |
License
MIT © lizhooh
