create 方法可以帮助我们创建一个自定义 hook 用于状态管理

const useSomeStore = create(stateCreatorFn)
1
type Create = {
2
<T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>): UseBoundStore<Mutate<StoreApi<T>, Mos>>;
3
<T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>) => UseBoundStore<Mutate<StoreApi<T>, Mos>>;
4
};

1stateCreatorFn

create 接收一个名为 stateCreatorFn 的函数作为参数。该函数的也接收三个参数,绝大多数情况下,我们只需要使用第一个参数即可

stateCreatorFn(setState, getState, store) {}
1
export const useStore = create((set) => ({
2
x: 0,
3
y: 0,
4
update: (event: MouseEvent) => set({
5
x: event.pageX,
6
y: event.pageY
7
}),
8
}))

3、create 返回值

create 函数运行之后返回一个 react hooks,我们可以利用返回的 hook 访问 getState setState getInitialState subscribe 四个方法。

例如,上一章的案例,我们可以利用 setState 进行改写来单独创建更新函数,注意观察 store.ts

预览
index.tsx
store.ts
1
import { useEffect } from 'react'
2
import { useStore, update } from './store'
3
4
export default function Counter() {
5
const { x, y } = useStore()
6
7
useEffect(() => {
8
window.addEventListener('mousemove', update)
9
return () => {
10
window.removeEventListener('mousemove', update)
11
}
12
}, [])
13
14
return (
15
<div className='text-center'>
16
鼠标当前位置
17
<div className='font-bold text-2xl mt-4'>{x}, {y}</div>
18
</div>
19
)
20
}

4、获取状态

在组件中,我们可以直接通过解构的方式获取状态

const { x, y } = useStore()

这种方式的好处就是写起来比较简洁优雅。但是在 zustand 中,他会存在很大的性能风险,因为 store 中其他状态的更新,当前组件也会受到影响从而导致冗余的 re-render。如果你确保 store 的状态不会在别的组件中更新,那么就可以这样使用。

另外一种方式就是使用 selector 对状态进行选取,它可以有效的避免冗余的 re-render,坏处就是看上去不够优雅。许多开发者也因为这个原因而选择放弃 zustand,这个主要看个人喜好

1
const x = useStore(state => state.x)
2
const y = useStore(state => state.y)

完整的案例如下

预览
index.tsx
store.ts
1
import { useEffect } from 'react'
2
import { useStore, update } from './store'
3
4
export default function Counter() {
5
const x = useStore(state => state.x)
6
const y = useStore(state => state.y)
7
8
useEffect(() => {
9
window.addEventListener('mousemove', update)
10
return () => {
11
window.removeEventListener('mousemove', update)
12
}
13
}, [])
14
15
return (
16
<div className='text-center'>
17
鼠标当前位置
18
<div className='font-bold text-2xl mt-4'>{x}, {y}</div>
19
</div>
20
)
21
}
下一篇
3、set
专栏首页
到顶
专栏目录