正如Zustand官网所描述,Zustand是一个不同于Redux的更加轻量、更加便捷、可拓展的React状态管理,小巧但功能非常强大。
基本使用
- 定义类型约束 State
在定义类型时,可以结合TypeScript来对state的数据类型进行约束,以减少错误的出现,确保状态的类型和值都是准确的。
type TCountState = {
count: number
add: () => void
sub: () => void
}
- 通过 create 方法创建 store
import { create } from 'zustand'
type TCountState = {
count: number
add: () => void
sub: () => void
}
export const countStore = create<TCountState>((set) => ({
count: 0,
add: () => set((state) => ({ count: state.count + 1 })),
sub: () => set((state) => ({ count: state.count - 1 })),
}));
count、add、sub等属性和方法要写在 (set) => ({ }) 里面,set 函数合并状态以实现状态更新。
- 在组件中使用 countStore
import { FC } from 'react'
import { countStore } from '@/store/counterStore'
const Counter: FC = () => {
const { count, add, sub } = countStore((state) => ({
count: state.count,
add: state.add,
sub: state.sub
}))
return (
<div className="counter">
<div>{count}</div>
<button onClick={() => add}>add</button>
<button onClick={() => sub}>sub</button>
</div>
)
}
export default Counter
通过解构的方式来访问 countStore 中的属性和方法。
实践优化
- 对属性的解构进行简化
上面在组件中使用 store 中的属性和方法的时候,解构相对复杂,在属性和方法较多的情况下会变得冗杂,对此可以修改 store 以简化使用。
- 修改 store
import { create } from 'zustand'
type TCountState = {
count: number
add: () => void
sub: () => void
}
export const countStore = create<TCountState>()((set) => ({
count: 0,
add: () => set((state) => ({ count: state.count + 1 })),
sub: () => set((state) => ({ count: state.count - 1 }))
}))
- 在组件中使用
import { FC } from 'react'
import { countStore } from '@/store/counterStore'
const Counter: FC = () => {
const { count, add, sub } = countStore()
return (
<div className="counter">
<div>{count}</div>
<button onClick={() => add}>add</button>
<button onClick={() => sub}>sub</button>
</div>
)
}
export default Counter
- 使用中间件实现状态存储的本地存储
可以使用Zustand提供的中间件来对 store 中的数据进行本地存储,避免在刷新后数据丢失。
import { create } from 'zustand'
import { persist } from 'zustand/middleware'
type TCountState = {
count: number
add: () => void
sub: () => void
}
export const countStore = create<TCountState>()(
persist(
(set) => ({
count: 0,
add: () => set((state) => ({ count: state.count + 1 })),
sub: () => set((state) => ({ count: state.count - 1 }))
}),
{
name: 'countStore'
}
)
)
这里使用 persist 来将属性和方法包裹,并传入一个 name,name 的值就是在本地存储中的 key。