Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(useList): support clearData #534

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/useList/__tests__/useList.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,42 @@ describe('Test useList hook', () => {
expect(result.current.params.total).toBe(0);
expect(result.current.error).toBe(undefined);
});

it('Should ONLY clear data while not reset loading', async () => {
const fetcher = jest.fn().mockImplementation(
() =>
new Promise((resolve) => {
setTimeout(() => {
resolve({
total: 1,
data: [{ uuid: 1 }],
});
}, 1000);
})
);

const { result } = renderHook(() =>
useList(fetcher, { current: 1, pageSize: 20, search: '' }, { immediate: false })
);
act(() => {
result.current.mutate({ current: 2 });
});

expect(result.current.loading).toBe(true);
expect(result.current.params.current).toBe(2);

act(() => {
result.current.clearData();
});
// clearData won't reset params and loading status
expect(result.current.loading).toBe(true);
expect(result.current.params.current).toBe(2);

act(() => {
result.current.clear();
});
// clear method will clear all data including params and loading status
expect(result.current.loading).toBe(false);
expect(result.current.params.current).toBe(1);
});
});
93 changes: 93 additions & 0 deletions src/useList/demos/query.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import React from 'react';
import { Input, Result, Table } from 'antd';
import { Empty, useList } from 'dt-react-component';

import getMockData, { type MockData } from './data';

export default () => {
const { error, params, loading, data, mutate, clearData } = useList<
MockData,
{ current: number; pageSize: number; search?: string }
>(
(params) => {
return new Promise<{
data: MockData[];
total: number;
}>((resolve) => {
setTimeout(() => {
resolve(getMockData(params));
}, 1000);
});
},
() => ({
current: 1,
pageSize: 20,
})
);

if (error) return <Result status={500} />;

return (
<>
<Input.Search
value={params.search}
onChange={(e) => {
mutate({ search: e.target.value }, { revalidate: false });
clearData();
}}
onSearch={() => mutate()}
style={{ marginBottom: 12 }}
/>
<Table
columns={[
{
key: 'name',
title: 'name',
dataIndex: 'name',
},
{
key: 'address',
title: 'address',
dataIndex: 'address',
},
{
key: 'company',
title: 'company',
dataIndex: 'company',
},
{
key: 'gender',
title: 'gender',
dataIndex: 'gender',
},
{
key: 'weight',
title: 'weight',
dataIndex: 'weight',
},
]}
onChange={(pagination) =>
mutate({ current: pagination.current, pageSize: pagination.pageSize })
}
size="small"
scroll={{ y: 200 }}
dataSource={data}
pagination={{
current: params.current,
pageSize: params.pageSize,
total: params.total,
}}
locale={{
emptyText: () =>
loading ? (
<Empty type="search" active description="搜索中" />
) : (
<Empty type="default" />
),
}}
rowKey="uuid"
bordered
/>
</>
);
};
1 change: 1 addition & 0 deletions src/useList/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ toc: content
<code src="./demos/options.tsx" title="相关配置" description="设置 immediate 值防止初始化的时候进行请求"></code>
<code src="./demos/mutate.tsx" title="相关配置" description="用 undefined 覆盖 prevPrams 时,需采用 functional 的写法 "></code>
<code src="./demos/mutateOptions" title="mutate相关配置" description="revalidate 修改后请求数据,clearData 请求前清除数据"></code>
<code src="./demos/query" title="搜索" description="支持修改后重置搜索"></code>

## API

Expand Down
50 changes: 43 additions & 7 deletions src/useList/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,45 @@ export interface IUseListOptions {
immediate?: boolean;
}

/**
* 返回值
*/
export interface UseListResponseState<
T extends Record<string, any>,
P extends Record<string, any>
> {
/**
* 请求是否执行中
*/
loading: boolean;
/**
* 请求的相关参数以及结果数据的总数
*/
params: P & { total: number };
/**
* 错误信息
*/
error?: Error;
/**
* 返回的数据
*/
data: T[];
mutate: (params?: Partial<P> | ((prev: P) => P), options?: IMutateOptions) => void;
/**
* 清空所有数据和状态
*/
clear: () => void;
/**
* 清空数据
*/
clearData: () => void;
}

export default function useList<T extends Record<string, any>, P extends Record<string, any>>(
fetcher: Fetcher<T, P>,
initialParams: P | (() => P),
rawOptions: IUseListOptions = { immediate: true }
) {
): UseListResponseState<T, P> {
const [error, setError] = useState<Error | undefined>(undefined);
const [data, setData] = useState<T[]>([]);
const [total, setTotal] = useState(0);
Expand Down Expand Up @@ -62,20 +96,22 @@ export default function useList<T extends Record<string, any>, P extends Record<

if (nextOptions.revalidate) {
if (nextOptions.clearData) {
setData([]);
setTotal(0);
setError(undefined);
clearData();
}
performFetch(tmp);
}
};

const clear = () => {
const clearData = () => {
setData([]);
setTotal(0);
setError(undefined);
};

const clear = () => {
clearData();
setParams(initialParams);
setLoading(false);
setError(undefined);
};

useEffect(() => {
Expand All @@ -84,5 +120,5 @@ export default function useList<T extends Record<string, any>, P extends Record<
}
}, []);

return { loading, params: { ...params, total }, error, data, mutate, clear };
return { loading, params: { ...params, total }, error, data, mutate, clear, clearData };
}
Loading