1 2 3 4 5
| ./store ├── createStore.ts // Action 与 store ├── selectors.ts // 状态派生 ├── initialState.ts // State 类型定义与 初始状态 └── index.ts
|
如此划分的依据本质上还是基于 State、Action 与 Selector 的三者切分:
initialState.ts:负责 State —— 添加状态类型与初始化状态值;
createStore.ts: 负责书写创建 Store 的方法与 Action 方法;
selectors.ts: 负责 Selector ——派生类选择器逻辑;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import type { ExternalScripts, IconfontIcon, IconUnit, ReactIcon } from '../types'; import { antdIconList } from '../contents/antdIcons';
export interface State { iconfontScripts: ExternalScripts[]; icon?: IconUnit; showEditor: boolean;
open: boolean; panelTabKey: 'antd' | 'iconfont'; filterKeywords?: string;
activeIconfontScript?: string; antdIconList: ReactIcon[]; iconfontIconList: IconfontIcon[]; }
export const initialState: State = { open: false, showEditor: false, panelTabKey: 'antd', filterKeywords: '', antdIconList,
iconfontScripts: [], iconfontIconList: [], onIconChange: null, };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import create from 'zustand';
import type { State } from './initialState'; import { initialState } from './initialState';
interface Action { resetIcon: () => void; togglePanel: () => void; selectIcon: (icon: IconUnit) => void; removeScripts: (url: string) => void; selectScript: (url: string) => void; toggleEditor: (visible: boolean) => void; addScript: (script: ExternalScripts) => void; updateScripts: (scripts: ExternalScripts[]) => void; }
export type Store = State & Action;
export const useStore = create<Store>((set, get) => ({ ...initialState,
resetIcon: () => { set({ icon: undefined }); },
selectIcon: (icon) => { set({ icon, open: false, filterKeywords: undefined }); },
addSript:()=>{ }, updateScripts:()=>{ }, removeScripts:()=>{ }, selectScript:async (url)=>{ } }));
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import type { Store } from './createStore'; import type { IconUnit } from '../types';
export const isEmptyIconfontScripts = (s: Store) => s.iconfontScripts.length === 0;
export const selectedListSelector = (s: Store): IconUnit[] => s.panelTabKey === 'iconfont' ? s.iconfontIconList : s.antdIconList;
export const isEmptyIconListSelector = (s: Store) => selectedListSelector(s).length === 0;
export const displayListSelector = (s: Store) => { const list = selectedListSelector(s); const { filterKeywords } = s;
return list.filter((i) => { if (!filterKeywords) return true;
switch (i.type) { case 'antd': case 'internal': return i.componentName.toLowerCase().includes(filterKeywords.toLowerCase());
case 'iconfont': return i.props.type.toLowerCase().includes(filterKeywords.toString()); } }); };
|
最后在 index.ts 中输出相应的方法和类型即可:
1 2 3 4 5
| export { useStore } from './createStore'; export type { Store } from './createStore'; export type { State } from './initialState'; export * from './selectors';
|
本文摘抄总结自 谈谈复杂应用的状态管理(下):基于 Zustand 的渐进式状态管理实践 - 知乎 (zhihu.com)