跳到主要内容

Store 与 Atom

@vef-framework-react/core 提供两种状态管理方式:基于 Zustand 的 store 和 Jotai atom。

Zustand Store

createStore

创建带有 subscribeWithSelectorimmer 中间件的全局绑定 store。

状态类型必须包含 name: string 字段。

import { createStore } from "@vef-framework-react/core";

interface CounterState {
name: string;
count: number;
increment: () => void;
reset: () => void;
}

export const useCounterStore = createStore<CounterState>(set => ({
name: "counter",
count: 0,
increment: () => {
set(state => {
state.count += 1;
});
},
reset: () => {
set(state => {
state.count = 0;
});
}
}));

在组件中使用:

const count = useCounterStore(state => state.count);
const increment = useCounterStore(state => state.increment);

createPersistedStore

创建持久化到 localStoragesessionStorage 的全局 store。

import { createPersistedStore } from "@vef-framework-react/core";

interface ThemeState {
colorScheme: "light" | "dark";
setColorScheme: (value: "light" | "dark") => void;
}

export const useThemeStore = createPersistedStore<ThemeState>(
set => ({
colorScheme: "light",
setColorScheme: colorScheme => {
set(state => {
state.colorScheme = colorScheme;
});
}
}),
{
name: "theme",
storage: "local",
selector: state => ({ colorScheme: state.colorScheme })
}
);

PersistenceOptions

选项类型说明
namestring唯一存储键名
storage"local" | "session"存储类型(默认:"local"
selector(state) => partial选择需要持久化的字段

createComponentStore

创建基于 React Context 的组件级 store,适合在页面或功能模块内共享状态,而不污染全局状态。

import { createComponentStore } from "@vef-framework-react/core";

interface PageState {
selectedId?: string;
setSelectedId: (id: string) => void;
}

export const {
StoreProvider: PageStoreProvider,
useStore: usePageStore,
useStoreApi: usePageStoreApi
} = createComponentStore<PageState>("MyPage", set => ({
setSelectedId: id => {
set(state => {
state.selectedId = id;
});
}
}));

用 Provider 包裹页面:

<PageStoreProvider>
<MyPage />
</PageStoreProvider>

携带初始状态:

<PageStoreProvider initialState={{ selectedId: "default" }}>
<MyPage />
</PageStoreProvider>

useDeepuseShallow

Zustand store 的选择器比较辅助函数:

import { useDeep, useShallow } from "@vef-framework-react/core";

// 浅比较(对象引用变化但值相同时避免重渲染)
const { count, name } = useCounterStore(useShallow(state => ({
count: state.count,
name: state.name
})));

// 深比较
const config = useConfigStore(useDeep(state => state.config));

类型导出

类型说明
SliceStateCreator<TState, TSlice, TPersist>store 切片的状态创建器类型
UnboundStore<TState>未绑定 React 的原始 Zustand store 类型
UseBoundStore<TState>绑定 store 的 hook 类型
UseBoundStoreWithPersist<TState>带持久化的绑定 store hook 类型
PersistenceOptions<TState, TSelectedState>createPersistedStore 的选项类型
StoreProviderProps<TInitialState>组件 store Provider 的 props 类型
UseStore<TState>useStore 的 hook 签名类型

Jotai Atom

适用于不需要完整 store 的轻量级一次性状态。

atom

import { atom } from "@vef-framework-react/core";

const modalAtom = atom({ open: false, data: null as UserRow | null });
const countAtom = atom(0);

useAtomuseAtomValueuseSetAtom

import { useAtom, useAtomValue, useSetAtom } from "@vef-framework-react/core";

// 读写
const [modal, setModal] = useAtom(modalAtom);

// 只读
const modal = useAtomValue(modalAtom);

// 只写
const setModal = useSetAtom(modalAtom);

AtomStoreProvidercreateAtomStore

用于隔离的 atom 作用域:

import { AtomStoreProvider, createAtomStore } from "@vef-framework-react/core";

const store = createAtomStore();

<AtomStoreProvider store={store}>
<IsolatedFeature />
</AtomStoreProvider>

useAtomStoregetDefaultAtomStore

import { useAtomStore, getDefaultAtomStore } from "@vef-framework-react/core";

// 组件内部
const store = useAtomStore();

// React 外部
const store = getDefaultAtomStore();
const value = store.get(countAtom);
store.set(countAtom, 1);

Atom 类型导出

类型说明
Atom<T>只读 atom 类型
PrimitiveAtom<T>可读写的原始 atom 类型
WritableAtom<T, Args, Result>可写 atom 类型
AtomGettergetter 函数类型
AtomSettersetter 函数类型
ExtractAtomValue<T>从 atom 中提取值类型
ExtractAtomArgs<T>从可写 atom 中提取参数类型
ExtractAtomResult<T>从可写 atom 中提取结果类型
SetStateAction<T>设置状态的 action 类型