Zustand
Zustand
是一个小巧、快速、可扩展的状态管理解决方案。它基于 Hooks
的易用的 API
。既没有模板化,也没有主观臆断,但却有足够的约定俗成的明确性和可变性。
安装
npm install zustand
定义状态
创建一个文件 src/store/count
可以把任何东西放进去:原始值、对象、函数。set
函数会合并状态
tsx
import { create } from 'zustand'
interface CountState {
count: number,
addCount: () => void,
resetCount: () => void,
updateCount: (n: number) => void,
}
export default create<CountState>((set) => ({
count: 0,
addCount: () => set((state) => ({ count: state.count + 1 })),
resetCount: () => set({ count: 0 }),
updateCount: (n: number) => set({ count: n }),
}))
注意: 更新状态数据时不要直接 set({ count: count + 1 })
这样相当于永远是初始值 0 + 1
我们需要根据 set
函数式中的 state
参数进行更新,这样可以确保每次的数据是最新的
使用状态
在页面中使用
tsx
import useCountStore from '@/store/count'
export default () => {
const count = useCountStore(state => state.count)
const addCount = useCountStore(state => state.addCount)
const resetCount = useCountStore(state => state.resetCount)
const updateCount = useCountStore(state => state.updateCount)
return (
<>
<h1>{count}</h1>
<button onClick={addCount}>增加</button>
<button onClick={resetCount}>重置</button>
<button onClick={() => updateCount(10)}>修改</button>
</>
)
}
或者这样
ts
const { count, addCount, resetCount, updateCount } = useCountStore(
(state) => ({ count: state.count, addCount: state.addCount, resetCount: state.resetCount, updateCount: state.updateCount })
)
也可以这样
tsx
import useCountStore from '@/store/count'
export default () => {
const { count, addCount, resetCount, updateCount } = useCountStore()
return (
<>
<h1>{count}</h1>
<button onClick={addCount}>增加</button>
<button onClick={resetCount}>重置</button>
<button onClick={() => updateCount(10)}>修改</button>
</>
)
}
这个写法虽然更加简约了,但不推荐。
因为只要 useCountStore
其中某个状态改变了,那么只要使用了它的所有组件都会重新渲染,从而导致性能问题。
而上面的使用方式虽然需要一个个引入,但只有引入的组件发生变化才会重新渲染组件,没有引入的不会触发重新渲染
持久化
将数据持久化存储,可以通过 persist
的第二个对象参数 name
配置存储名称以及 storage
定义存储方式,可以选择是 localStorage
或 sessionStorage
typescript
import { create } from 'zustand'
import { persist, createJSONStorage } from 'zustand/middleware'
interface CountState {
count: number,
addCount: () => void,
resetCount: () => void,
updateCount: (n: number) => void,
}
export default create(
persist<CountState>(
(set) => ({
count: 0,
addCount: () => set((state) => ({ count: state.count + 1 })),
resetCount: () => set({ count: 0 }),
updateCount: (n: number) => set({ count: n }),
}),
{
name: "count_storage", // 持久化存储的名称
storage: createJSONStorage(() => localStorage), // 持久化存储方式
}
)
)
模块化
如果有多个状态,我们可以进行模块化处理,方便统一管理
创建文件:src/store/index.ts
tsx
import useCountStore from './modules/count'
import useUserStore from './modules/user'
export { useCountStore, useUserStore }
在页面中使用
tsx
import { useCountStore } from '@/store'