Open findxc opened 1 year ago
官方文档: https://docs.pmnd.rs/zustand/getting-started/introduction
优点:
因为这个库我去学了 TS 哈哈哈,以前只会定义 interface ,现在会一点类型推导了 ✌️
比如退出登录时希望重置所有 store 值为初始状态。参见 https://docs.pmnd.rs/zustand/guides/how-to-reset-state 二次封装一下 create 即可。
create
import { create } from 'zustand' interface BearState { bears: number setBears: (value: number) => void } const useBearStore = create<BearState>(set => ({ bears: 0, setBears: value => set({ bears: value }), }))
比如上面的代码, BearState 那里我需要写 setBears 的 TS 定义,在 create 时我也需要写 setBears 的具体实现。我们能不能自动生成相应的 setState: value => set({ state: value }) ?
BearState
setBears
setState: value => set({ state: value })
setBears 的 TS 定义可以通过推导来得到:
type Actions<T> = { [P in keyof T & string as `set${Capitalize<P>}`]: (value: T[P]) => void }
Actions<{ bears: number }> 结果如下:
Actions<{ bears: number }>
setBears 这个函数也是可以根据 { bears: 0 } 来类似生成的。
{ bears: 0 }
封装后的 create 完整代码如下:
// create.ts import { create as _create } from 'zustand' type Actions<T> = { [P in keyof T & string as `set${Capitalize<P>}`]: (value: T[P]) => void } const resetters: (() => void)[] = [] const create = <State, A = object>(initialState, extraActions?) => { const store = _create<State & Actions<State> & A>((set, get) => ({ ...initialState, // 根据 initialState 自动生成对应的 actions ...Object.keys(initialState).reduce((total, key) => { const functionName = `set${key[0].toUpperCase()}${key.slice(1)}` // @ts-ignore total[functionName] = value => set({ [key]: value }) return total }, {}), // 也支持传入自定义的 actions ...(extraActions ? extraActions(set, get) : {}), })) resetters.push(() => { store.setState(initialState) }) return store } export const resetAllStores = () => { for (const resetter of resetters) { resetter() } } export default create
一个使用例子:
// useGlobalStore.ts import create from './create' type State = { name: string permissions: string[] } const initialState: State = { name: '', permissions: [], } const extraActions = set => ({ updateUser: (user: Pick<State, 'name' | 'permissions'>) => set(user), }) const useGlobalStore = create<State, ReturnType<typeof extraActions>>( initialState, extraActions ) export default useGlobalStore
useGlobalStore 使用时的类型提示如下:
useGlobalStore
setName 和 setPermissions 的 TS 定义和函数实现是自动生成的,然后我们也支持在 create 时传入 updateUser 这样的自定义 actions 。
setName
setPermissions
updateUser
Valtio 也是一个状态管理库,文档见 https://github.com/pmndrs/valtio
一个简单例子如下:
import { proxy, useSnapshot } from 'valtio' const state = proxy({ count: 0, text: 'hello' }) function Counter() { const snap = useSnapshot(state) return ( <div> {snap.count} <button onClick={() => ++state.count}>+1</button> </div> ) }
我不太喜欢 ++state.count 这种直接去改状态的方式,我更喜欢通过一个函数去更新状态。这样当我希望知道哪些地方有改动某个状态时,我全局搜索对应的函数就行了, ++state.count 这种方式不利于定位代码。
++state.count
最喜欢 jotai,用起来和 useState 没差。有个一小差别,zustand 的类型需要自己通过泛型标,jotai 不用
官方文档: https://docs.pmnd.rs/zustand/getting-started/introduction
我的感受
优点:
因为这个库我去学了 TS 哈哈哈,以前只会定义 interface ,现在会一点类型推导了 ✌️
实际场景一:怎么 reset 所有 store 的值
比如退出登录时希望重置所有 store 值为初始状态。参见 https://docs.pmnd.rs/zustand/guides/how-to-reset-state 二次封装一下
create
即可。实际场景二:可以根据 initialState 来自动生成对应的 actions 函数吗
比如上面的代码,
BearState
那里我需要写setBears
的 TS 定义,在create
时我也需要写setBears
的具体实现。我们能不能自动生成相应的setState: value => set({ state: value })
?setBears
的 TS 定义可以通过推导来得到:Actions<{ bears: number }>
结果如下:setBears
这个函数也是可以根据{ bears: 0 }
来类似生成的。封装后的 create 完整代码如下:
一个使用例子:
useGlobalStore
使用时的类型提示如下:setName
和setPermissions
的 TS 定义和函数实现是自动生成的,然后我们也支持在create
时传入updateUser
这样的自定义 actions 。和 Valtio 的使用方式的区别
Valtio 也是一个状态管理库,文档见 https://github.com/pmndrs/valtio
一个简单例子如下:
我不太喜欢
++state.count
这种直接去改状态的方式,我更喜欢通过一个函数去更新状态。这样当我希望知道哪些地方有改动某个状态时,我全局搜索对应的函数就行了,++state.count
这种方式不利于定位代码。