useRequest.ts 2.9 KB
Newer Older
P
Peter Pan 已提交
1
import type {ConfigInterface, keyInterface, responseInterface} from 'swr';
2 3
import {useEffect, useMemo} from 'react';

4
import ee from '~/utils/event';
5
import type {fetcherFn} from 'swr/dist/types';
P
Peter Pan 已提交
6 7
import {toast} from 'react-toastify';
import useSWR from 'swr';
8 9 10 11 12

type Response<D, E> = responseInterface<D, E> & {
    loading: boolean;
};

P
Peter Pan 已提交
13 14 15
function useRequest<D = unknown, E extends Error = Error>(key: keyInterface): Response<D, E>;
function useRequest<D = unknown, E extends Error = Error>(key: keyInterface, fetcher?: fetcherFn<D>): Response<D, E>;
function useRequest<D = unknown, E extends Error = Error>(
16 17
    key: keyInterface,
    fetcher?: fetcherFn<D>,
18
    config?: ConfigInterface<D, E, fetcherFn<D>>
19
): Response<D, E>;
P
Peter Pan 已提交
20
function useRequest<D = unknown, E extends Error = Error>(
21 22 23 24 25
    key: keyInterface,
    fetcher?: fetcherFn<D>,
    config?: ConfigInterface<D, E, fetcherFn<D>>
): Response<D, E> {
    const {data, error, ...other} = useSWR<D, E>(key, fetcher, config);
P
Peter Pan 已提交
26
    const loading = useMemo(() => !!key && data === void 0 && !error, [key, data, error]);
P
Peter Pan 已提交
27 28 29 30 31 32 33 34 35 36

    useEffect(() => {
        if (error) {
            toast(error.message, {
                position: toast.POSITION.TOP_CENTER,
                type: toast.TYPE.ERROR
            });
        }
    }, [error]);

37 38 39
    return {data, error, loading, ...other};
}

P
Peter Pan 已提交
40 41
function useRunningRequest<D = unknown, E extends Error = Error>(key: keyInterface, running: boolean): Response<D, E>;
function useRunningRequest<D = unknown, E extends Error = Error>(
42 43 44 45
    key: keyInterface,
    running: boolean,
    fetcher?: fetcherFn<D>
): Response<D, E>;
P
Peter Pan 已提交
46
function useRunningRequest<D = unknown, E extends Error = Error>(
47 48 49
    key: keyInterface,
    running: boolean,
    fetcher?: fetcherFn<D>,
50
    config?: Omit<ConfigInterface<D, E, fetcherFn<D>>, 'dedupingInterval' | 'errorRetryInterval'>
51
): Response<D, E>;
P
Peter Pan 已提交
52
function useRunningRequest<D = unknown, E extends Error = Error>(
53 54 55
    key: keyInterface,
    running: boolean,
    fetcher?: fetcherFn<D>,
56
    config?: Omit<ConfigInterface<D, E, fetcherFn<D>>, 'dedupingInterval' | 'errorRetryInterval'>
57 58 59 60
) {
    const c = useMemo<ConfigInterface<D, E, fetcherFn<D>>>(
        () => ({
            ...config,
61 62 63
            refreshInterval: running ? config?.refreshInterval ?? 15 * 1000 : 0,
            dedupingInterval: config?.refreshInterval ?? 15 * 1000,
            errorRetryInterval: config?.refreshInterval ?? 15 * 1000
64 65 66 67 68 69 70 71 72 73 74 75 76
        }),
        [running, config]
    );

    const {mutate, ...others} = useRequest(key, fetcher, c);

    // revalidate immediately when running is set to true
    useEffect(() => {
        if (running) {
            mutate();
        }
    }, [running, mutate]);

77
    useEffect(() => {
P
Peter Pan 已提交
78
        ee.on('refresh', mutate);
79
        return () => {
P
Peter Pan 已提交
80
            ee.off('refresh', mutate);
81 82 83
        };
    }, [mutate]);

84 85 86
    return {mutate, ...others};
}

87
export default useRequest;
88
export {useRunningRequest};