Skip to content

Commit

Permalink
feat(Store): 新增 useStore 接口
Browse files Browse the repository at this point in the history
BREAKING CHANGE: 嵌套 Store 不再 merge
  • Loading branch information
tolerance-go committed Apr 13, 2024
1 parent 0bb679b commit c422885
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 77 deletions.
77 changes: 22 additions & 55 deletions src/Store/demos/nested.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,26 @@
import { Button, Cascader, Form, Icon, Input, Tooltip } from 'antd';
import React, { useContext } from 'react';
import { DrawerForm, ProDescriptions, SearchTable, Store, StoreContext } from 'widgets-v3';
import {
DrawerForm,
ProDescriptions,
SearchTable,
Store,
StoreContext,
useStore,
} from 'widgets-v3';
import delay from 'delay';

const residences = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];

const Child = () => {
const stores = useContext(StoreContext);
return <div style={{ border: '1px solid', padding: 10 }}>{JSON.stringify(stores)}</div>;
const component = useStore('component');
const global = useStore('global');
const unknown = useStore('unknown');
return (
<div style={{ border: '1px solid', padding: 10 }}>
<div>component: {JSON.stringify(component)}</div>
<div>global: {JSON.stringify(global)}</div>
<div>unknown: {JSON.stringify(unknown)}</div>
</div>
);
};

export default () => (
Expand All @@ -55,23 +35,22 @@ export default () => (
}}
name="global"
>
{({ global }) => {
{(global) => {
return (
<div style={{ border: '1px solid', padding: 10 }}>
<div>username: {global.userInfo?.nickname}</div>
{JSON.stringify(global)}
<Store
request={async () => {
await delay(1000);
return {
componentKey: 'componentKey',
componentInfo: 'componentInfo',
};
}}
name="component"
>
{({ component, global }) => {
{(component) => {
return (
<div style={{ border: '1px solid', padding: 10 }}>
<div>global: {JSON.stringify(global)}</div>
<div>component: {JSON.stringify(component)}</div>
<Child />
</div>
Expand Down Expand Up @@ -270,18 +249,6 @@ export default () => (
>
{getFieldDecorator('nickname', {})(<Input />)}
</Form.Item>,
<Form.Item label="Habitual Residence">
{getFieldDecorator('residence', {
initialValue: ['zhejiang', 'hangzhou', 'xihu'],
// rules: [
// {
// type: 'array',
// required: true,
// message: 'Please select your habitual residence!',
// },
// ],
})(<Cascader options={residences} />)}
</Form.Item>,
];
},
}}
Expand Down
38 changes: 17 additions & 21 deletions src/Store/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
import React, { createContext, useContext, useEffect, useMemo, useRef, useState } from 'react';
import { Spin, message } from 'antd';
import React, { createContext, useContext, useEffect, useRef, useState } from 'react';
import { Spin } from 'antd';
import { handleError } from 'src/_utils/handleError';

type StoreProps = {
children?: (data: Record<string, any>) => React.ReactNode;
request?: () => Promise<Record<string, any>>;
name?: string; // 新增属性,用于标识每个Store
name?: string; // 用于标识每个Store的可选属性
};

export const useStore = (name: string) => {
const context = useContext(StoreContext);
return context[name];
};

// 创建一个context,用于保存按名称索引的数据
export const StoreContext = createContext<Record<string, any>>({});

const Store = ({ children, request, name }: StoreProps) => {
const [loading, setLoading] = useState(false);
const [data, setData] = useState<Record<string, any>>({});
const requestCounterRef = useRef(0);

// 使用 useContext 获取上级 Store 提供的数据
const parentData = useContext(StoreContext);
const context = useContext(StoreContext); // 使用context更新自己

const fetch = async () => {
if (!request) return;
Expand All @@ -26,16 +31,12 @@ const Store = ({ children, request, name }: StoreProps) => {

if (currentRequestIndex === requestCounterRef.current) {
setData(newData);
if (name) {
context[name] = newData; // 如果提供了名称,则在context中设置数据
}
}
} catch (error) {
let errorMessage;
if (typeof error === 'string') {
errorMessage = error;
} else if (error instanceof Error) {
errorMessage = error.message;
}
console.log(error);
message.error(errorMessage || '请求视图数据失败');
handleError(error, '请求视图数据失败');
} finally {
if (currentRequestIndex === requestCounterRef.current) {
setLoading(false);
Expand All @@ -47,14 +48,9 @@ const Store = ({ children, request, name }: StoreProps) => {
fetch();
}, []);

// 提供更新后的数据给子组件
const value = useMemo(() => {
return name ? { ...parentData, [name]: data } : data;
}, [name, parentData, data]);

return (
<StoreContext.Provider value={value}>
<Spin spinning={loading}>{children?.(value)}</Spin>
<StoreContext.Provider value={context}>
<Spin spinning={loading}>{children?.(data)}</Spin>
</StoreContext.Provider>
);
};
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export { default as EditableTabs } from './EditableTabs';
export { default as TabsForm } from './TabsForm';
export { default as FormDependency } from './FormDependency';
export { default as LoginForm } from './LoginForm';
export { default as Store, StoreContext } from './Store';
export { default as Store, StoreContext, useStore } from './Store';
export { default as FormField } from './FormField';
export { default as EditableGroups } from './EditableGroups';
export { default as GroupsForm } from './GroupsForm';
Expand Down

0 comments on commit c422885

Please sign in to comment.