123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- import {
- createPageContext,
- createSearchContext,
- useContextSection,
- usePage,
- useTableSearchState,
- } from '@hooks';
- import {BaseListResult, GetBaseListType, ListParams, OriginalListParams} from '@models';
- import {useQuery} from '@tanstack/react-query';
- import {shallowEqual} from '@utils';
- import {useLatest} from 'ahooks';
- import {useEffect, useRef, useState} from 'react';
- type UseQueryListResult<D extends BaseListResult, T extends unknown[] = GetBaseListType<D>[]> = [
- {
- count: number;
- data: T;
- isFetching: boolean;
- },
- {refetch: () => void},
- ];
- type UseQueryListOptions<
- P extends ListParams,
- R extends BaseListResult,
- T extends Array<unknown> = GetBaseListType<R>[],
- > = {
- queryFn: (params: P, signal?: AbortSignal) => R;
- params: OriginalListParams<P>;
- pageContext: ReturnType<typeof createPageContext>;
- searchContext: ReturnType<typeof createSearchContext>;
- formatResult?: (data: Awaited<R>) => T;
- };
- export function useQueryTableList<
- P extends ListParams,
- R extends BaseListResult,
- T extends Array<unknown> = GetBaseListType<R>[],
- >({
- queryFn,
- params,
- pageContext,
- searchContext,
- formatResult,
- }: UseQueryListOptions<P, R, T>): UseQueryListResult<R, T> {
- const [count, setCount] = useState(0);
- const [{page, pageSize}, {onCurrentPageChange}] = usePage(pageContext);
- const prevData = useRef<T>([] as unknown as T);
- const prevParams = useRef(params);
- const formatResultFn = useLatest(formatResult);
- const {
- data = [] as unknown as T,
- isFetching,
- refetch,
- } = useQuery<T>({
- queryKey: [queryFn.name, page, pageSize, ...Object.values(params)],
- async queryFn({signal}) {
- /**
- * 当参数发生改变说明请求内容发生变化
- * 如果当前页码不为1需要跳转到第1页查询
- */
- if (page !== 1 && !shallowEqual(prevParams.current, params)) {
- prevParams.current = params;
- onCurrentPageChange(1);
- // 这里可以返回一个空数组
- // 记录上一次数据是为了展示 防止闪烁
- return prevData.current;
- }
- /**
- * 有可能参数发生变化但是页码为1 第一步不会拦截
- * 这里确保参数是最新的参数
- */
- prevParams.current = params;
- const data = await queryFn(
- {
- ...params,
- page: page.toString(),
- limit: pageSize.toString(),
- } as P,
- signal,
- );
- if (data.msg === '200') {
- const {total, list} = data.data;
- /**
- * 场景:当页面只有一个数据的时候 删除了页码改为前一个 但是数据请求还是当前页码
- * 需要判断当前是否无数据并且页码大于1 满足时跳转到前一个页面
- */
- page > 1 && list.length === 0 && onCurrentPageChange(page - 1);
- setCount(total);
- }
- let res: T;
- formatResultFn.current
- ? (res = formatResultFn.current(data))
- : (res = data.msg === '200' ? (data.data.list as unknown as T) : ([] as unknown as T));
- return (prevData.current = res);
- },
- placeholderData: [] as unknown as T,
- keepPreviousData: true,
- });
- const [, searchChange] = useTableSearchState(searchContext);
- // 保持更新搜索表格的查询状态
- useEffect(
- function () {
- searchChange(isFetching);
- },
- [isFetching, searchChange],
- );
- const searchDispatch = useContextSection(searchContext, state => state[1]);
- useEffect(
- function () {
- searchDispatch({type: 'CHANGE_SEARCH_FUNCTION', payload: refetch});
- },
- [refetch, searchDispatch],
- );
- return [
- {
- count,
- data,
- isFetching,
- },
- {refetch},
- ];
- }
|