react 防抖 hooks 封装 ( 技术栈 react+antd 拿来就能用)

// 共用防抖hook
import { useState, useMemo, useRef, useEffect } from 'react';
import _ from 'lodash';

// {
//   api:url, // 请求路径,必须
//   keywordName:'search', // 请求查询关键字name , 不传默认search
//   otherParams:{ // 其他请求参数,选传
//     simple:1,
//   },
//   transformKeys:{ // 转换key,必须
//     label:'vehicle_number',
//     value:'id',
//     other:['wheel_info'] // 如需要使用接口中返回的其他信息,直接把key放入数组, 选传
//   },
//   relationParams:{ // 依赖的动态参数,这个参数变化,会重新发起请求,选传
//     key:'',
//     value:'',
//   }
// }

function useFetchDebounceSelect ({
  api,
  keywordName = 'search',
  otherParams = {},
  transformKeys = {},
  debounceTimeout = 1000,
  relationParams = {},
}) {
  
  const [fetching, setFetching] = useState(false);
  const fetchRef = useRef(0);

  useEffect(() => {
    debounceFetcher('', relationParams);
  },[relationParams?.value])

  const [list, setList] = useState([])

  const debounceFetcher = useMemo(() => {
    const loadOptions = (value, relationParams) => {
      fetchRef.current += 1;
      const fetchId = fetchRef.current;

      setList([]);
      setFetching(true);

      const params = {
        page: 1,
        rows: 20,
        [keywordName]: value,
        ...otherParams,
      }

      if (relationParams?.key) {
        params[relationParams.key] = relationParams.value;
      }

      api(params).then((newOptions) => {
        if (fetchId !== fetchRef.current) {
          return;
        }
        setList(newOptions.data.list);
        setFetching(false);
      });
    };

    return _.debounce(loadOptions, debounceTimeout);
  }, [debounceTimeout]);

  const getOtherData = (item) => {
    let otherData = {}
    if (transformKeys?.other?.length) {
      transformKeys.other.map(key => {
        otherData[key] = item[key];
      })
    }
    return otherData;
  }
  

  return {
    type: 'select',
    options: list.map(item => {
      const otherData = getOtherData(item)
      return {
        label: item[transformKeys.label],
        value: item[transformKeys.value],
        ...otherData,
      }
    }),
    other: {
      placeholder:'请选择'
      labelInValue:true,
      filterOption: false,
      showSearch: true,
      loading: fetching,
      onSearch: (v) => debounceFetcher(v),
    }
  }
}

export default useFetchDebounceSelect;
// 使用防抖hook基于业务二次封装:

// 示例1: 获取某个列表
import useFetchDebounceSelect from './useFetchDebounceSelect'
import { url } from '@/api'

function useFetchxxxList () {

  return useFetchDebounceSelect({
    api:url,
    keywordName:'name', // 请求查询关键字name
    transformKeys:{
      label:'name',
      value:'id',
    }
  })
 
};

export default useFetchxxxList;

// 最终业务组件中使用以上hook:

// 引入
import useFetchxxxList from '@/hooks/useFetchxxxList';
import { Select } from 'antd'

//业务组件
export default function() {

  // 在组件内调用hook
  const { other, options } = useFetchxxxList();

  return (
	  <Select {...other} name="xxx" >
	    {options.map(({value, label}) => <Option key={value} value={value}>{label}</Option>))}
	  </Select>
  )


}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值