状态管理在现在的前端项目成为了必不可少的环节,三大框架也相继推出了自己的状态管理工具。当然也有一些非常优秀的第三方状态管理工具,比如:flux、mobx、dva、zustand等,今天我们就来了解下这款轻量级的状态管理工具-zustand。
一、安装
npm install zustand
// 或者
yarn add zustand
二、使用
创建状态管理及在组件中使用。
import create from 'zustand'
const useStore = create((set) => ({
count: 1,
inc: () => set((state) => ({ count: state.count + 1 })),included
}))
export default function MyApp() {
const { count, inc } = useStore()
return (
<div className="counter">
<span>{count}</span>
<button onClick={inc}>one up</button>
</div>
)
}
清除状态管理
import omit from 'lodash-es/omit'
const useFishStore = create((set) => ({
salmon: 1,
tuna: 2,
deleteEverything: () => set({}, true), // 清除所有的state,包括actions
deleteTuna: () => set((state) => omit(state, ['tuna']), true), // 只清除"tuna"
}))
异步操作
const useFishStore = create((set) => ({
fishies: {},
fetch: async (pond) => {
const response = await fetch(pond)
set({ fishies: await response.json() })
},
}))
在actions中读取state
const useSoundStore = create((set, get) => ({
sound: "grunt",
action: () => {
const sound = get().sound
// ...
}
})
三、create原型链上的方法
const useDogStore = create(() => ({ paw: true, snout: true, fur: true }))
// 主动性获取state的最新状态,可以在非组件环境下使用
const paw = useDogStore.getState().paw;
// 订阅state的变化,并做出相应的处理
const unsub = useDogStore.subscribe(console.log);
// 更新state,会触发subscribe
useDogStore.setState({ paw: false });
// 移除订阅
unsub();
// 销毁state,包括订阅
useDogStore.destroy()
// 在组件中使用
const Component = () => {
const paw = useDogStore((state) => state.paw)
...
getState
可以在组件外或者主动性获取到最新的状态。
setState
可以更新state,如果有subscribe会触发。
subscribe
可以订阅state的改变。
如果需要只订阅某个state,zustand也提供了中间件进行协助。
// subscribe(selector, callback, options?: { equalityFn, fireImmediately }): Unsubscribe
import { subscribeWithSelector } from 'zustand/middleware'
import shallow from 'zustand/shallow'
const useDogStore = create(
subscribeWithSelector(() => ({ paw: true, snout: true, fur: true }))
)
// 订阅”paw“的改变
const unsub2 = useDogStore.subscribe((state) => state.paw, console.log)
// 回调函数可返回旧的状态
const unsub3 = useDogStore.subscribe(
(state) => state.paw,
(paw, previousPaw) => console.log(paw, previousPaw)
)
// 可选的相等函数
const unsub4 = useDogStore.subscribe(
(state) => [state.paw, state.fur],
console.log,
{ equalityFn: shallow }
)
// 立即订阅并启动
const unsub5 = useDogStore.subscribe((state) => state.paw, console.log, {
fireImmediately: true,
})
destroy
销毁整个state 。
四、注意事项
1.数据的获取方式
实例中的三种数据获取方式均为允许的,不过略有区别。
通过useStore.getState()可以在组件外或者主动性获取到最新的状态。
useStore()则是以hook的形式,在组件内使用,且create创建的任何状态改变都将触发组件的更新。
useStore((state) => state.age)与useStore()类似,唯一的区别是只有在“age”字段更新时,组件才会被更新。
import create from 'zustand'
const useStore = create((set) => ({
name: "xiaoMing",
age: 18,
}))
const name = useStore.getState().name; // "xiaoMing"
const Component = () => {
const state = useStore(); // {name: "xiaoMing", age: 18}
// 或者
const age = useStore((state) => state.age); // "xiaoMing"
...