纯干货之自定义请求hooks

import { useState } from 'react';
import { fetchRequest } from './ajax';
type RequestMethod = 'GET' | 'POST' | 'DELETE' | 'PATCH' | 'PUT' | 'HEAD' | 'OPTIONS' | 'CONNECT'
/**
 * 1. 解决每个函数都要统一写try/catch的流程
 * 2. 解决发送请求需要手动加锁防止多次重复请求的痛点
 * 3. 不需要在手动useState loading了~,直接获取fetching值
 * @param getFunction 发送请求的函数
 * @param params 参数
 * @param isUpload 是否是上传请求
 */

// R, P支持泛型
// R: 返回的数据类型
// P: 请求参数的类型
function UseFetch<R, P>(
    method: RequestMethod,
    url?: string,
    params?: P,
    isUpload?: boolean,
): [
        (url, params?: Partial<P>) => Promise<R>,
        boolean,
        R,
    ] {
    // type ErrorFunction = ((fn?: (err: any) => void) => void) | null;
    const [res, setRes] = useState();// 返回的数据
    const [loading, setLoading] = useState(false);
    // const [failed, setFailed] = useState<ErrorFunction>(null);
    // 参数也许并不是每次都完整需要 Partial<P>
    const fetchData = (fetchUrl?: string, fetchParams?: Partial<P>): Promise<R> => {
         if (loading) {
            return Promise.resolve(false);
        }
        const tempUrl = fetchUrl || url;
        const tempParams = fetchParams || params;
        setLoading(true);
        const re = new Promise<R>((resolve, reject) => {
            // 这里是封装的请求方法,可替换成自己项目组内部的
            fetchRequest({
                url: tempUrl,
                method,
                data: tempParams,
                isUpload
            }).then((data: R) => {
                setRes(data);
                resolve(data);
            }).catch((err) => {
                console.log(err);
                // failed && failed(err);
                reject();
            }).finally(() => setLoading(false));
        });
        return re;
    };

    // 首次执行只请求一次
    // useEffect(() => {
    //     execute && fetchData(params);
    // }, []);

    /**
     * res 返回的数据
     * fetching 是否在请求中
     * fetchData 手动再次触发请求
     * setError 当发生请求错误时,需要执行的回掉函数
     */
    return [fetchData, loading, res];
}

export function useGetFetch<R, P>(url?: string, params = {}, isUpload?): [
    (url, params?: Partial<P>) => Promise<R>,
    boolean,
    R,
] {
    // Object.assign(params || {}, {
    //     timestamp: Date.now()
    // });
    return UseFetch('GET', url, params, isUpload);
}


export function usePostFetch<R, P>(url?: string, params = {}, isUpload?): [
    (url, params?: Partial<P>) => Promise<R>,
    boolean,
    R,
] {
    // Object.assign(params || {}, {
    //     timestamp: Date.now()
    // });
    return UseFetch('POST', url, params, isUpload);
}

  使用方法

import React, { useEffect, useState, useCallback, useRef } from "react";
import { usePostFetch } from "UtilPath/http/useAjax";

const hooks = () => {
  const [doSubmit, submitLoading] = usePostFetch<string, object>();
    const submit=()=>{
        doSubmit('url',"params").then(()=>{
            // .....
        })
    }
  return <div onClick={submit}> 按钮</div>;
};


存着~~~~

posted @ 2021-11-18 17:12  Judy倩倩  阅读(212)  评论(0)    收藏  举报