官网:docs.pmnd.rs/zustand/get…
安装
npm install zustand
特点
- 状态共享:默认不需要 Provider。直接声明一个 hooks 式的 useStore 后就可以在不同组件中进行调用。
- 状态变更:函数可以直接写,不用区分同步或者异步,默认将所有的函数保持同一引用(不会造成额外的重复渲染)。
get 对象,使得我们可以用 get 方法直接拿到当前 store 中最新的 state 快照
- 状态派生:用独立文件来管理派生状态(似useMemo)
- 性能优化:派生状态不会因数据不安话触发组件重新渲染
- 数据分形与状态组合:更容易拆分并组织代码,使用基于这种分形架构下的各种中间件(这点还没看懂)
- 多环境集成:不在 react 环境内的状态数据,如图表、画布、3D 场景直接拿值
- 测试方便:用test-library/react-hooks
使用
创建并绑定
import { create } from 'zustand'
const useStore = create((set) => ({
bears: 0,
increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
removeAllBears: () => set({ bears: 0 }),
}))
function BearCounter() {
const bears = useStore((state) => state.bears)
return <h1>{bears} around here...</h1>
}
function Controls() {
const increasePopulation = useStore((state) => state.increasePopulation)
return <button onClick={increasePopulation}>one up</button>
}
状态派生,入参为完整的store
export const nameSelector = (s) => return(s.name || '');
const name = useStore(nameSelector);
const iconList = useStore(displayListSelector, isEqual);
const selector = (s: Store) => ({
panelTabKey:s.panelTabKey,
icon:s.icon
});
const PickerPanel = () => {
const {panelTabKey, icon} = useStore(displayListSelector, shallow);
}
异步
const initialState = { designId: undefined, loading: false };
export const useStore = create((set, get) => ({
...initialState,
deprecateDraft: async () => {
set({ loading: true });
const res = await dispatch('/hitu/remote/ds/deprecate-draft', get().designId);
set({ loading: false });
if (res) { message.success('草稿删除成功'); }
},
refetch: () => {
if (get().designId) {
mutateKitchenSWR('/hitu/remote/ds/versions', get().designId);
}
},
})
多环境集成
const useDogStore = create(() => ({ paw: true, snout: true, fur: true }))
const paw = useDogStore.getState().paw
useDogStore.setState({ paw: false })
const Component = () => {
const paw = useDogStore((state) => state.paw) ...
组织架构
./store
├── createStore.ts
├── selectors.ts
├── initialState.ts
└── index.ts
devtools
export type Store = State & Action;
export const createStore = ()=> create<Store>()(devtools((set, get) => ({
...initialState,
selectIcon: (icon) => {
set({ icon, open: false, filterKeywords: undefined },false, "选择 Icon");
get().onIconChange?.(icon);
},
}),{ name: 'IconPicker' }));
链接:
juejin.cn/post/717721…
juejin.cn/post/718246…