美文网首页
React DebounceSelect 组件 自用

React DebounceSelect 组件 自用

作者: 很好就这样吧 | 来源:发表于2023-04-12 18:27 被阅读0次

    原生属性的继承

    export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {}
    

    原生属性的重写

    // 代表继承除type外,所有的input属性
    export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>,'type'> { 
      type: InputType
    }
    
    import React, { useEffect, useMemo, useRef, useState } from 'react'
    import { Select, Spin } from 'antd'
    import type { SelectProps } from 'antd/es/select'
    import { debounce } from '@/utils/util'
    
    export interface DebounceSelectProps<ValueType = any>
      extends Omit<SelectProps<ValueType | ValueType[]>, 'options' | 'children'> {
      fetchOptions: (search: string) => Promise<IOption[]>
      debounceTimeout?: number
      // 值为空的时候过滤
      filterEmpty?: boolean
      // 首次加载组件搜索的值,传入则触发搜索
      initialSearchKey?: string
    }
    
    type IOption = {
      key?: string
      label: React.ReactNode
      value: string | number
    }
    
    function DebounceSelect<ValueType = any>({
      fetchOptions,
      debounceTimeout = 600,
      filterEmpty = true,
      initialSearchKey,
      ...props
    }: DebounceSelectProps<ValueType>) {
      const [fetching, setFetching] = useState(false)
      const [options, setOptions] = useState<IOption[]>([])
      const fetchRef = useRef(0)
    
      const debounceFetcher = useMemo(() => {
        const loadOptions = (value: string) => {
          fetchRef.current += 1
          const fetchId = fetchRef.current
          setOptions([])
          // if (filterEmpty && !value) {
          //   return
          // }
          setFetching(true)
          fetchOptions(value).then((newOptions) => {
            if (fetchId !== fetchRef.current) {
              // for fetch callback order
              return
            }
    
            setOptions(newOptions)
            setFetching(false)
          })
        }
    
        return debounce(loadOptions, debounceTimeout)
      }, [fetchOptions, debounceTimeout, filterEmpty])
    
      useEffect(() => {
        if (initialSearchKey !== undefined) {
          debounceFetcher(initialSearchKey)
        }
      }, [initialSearchKey])
    
      return (
        <Select
          showSearch
          filterOption={false}
          onSearch={debounceFetcher}
          notFoundContent={fetching ? <Spin size="small" /> : null}
          {...props}
          options={options}
        />
      )
    }
    
    export default DebounceSelect
    
    
    //index.tsx
    
      const onNameSearch = (name: string) => {
        return queryNamesList(name).then((res) => {
          return res?.data?.map((item) => ({
            label: item.name,
            value: item.id,
          }))
        })
      }
    
    <Form.Item
      label="名称"
      name="name"
      rules={[{ required: true, message: '请选择名称' }]}
    >
      <DebounceSelect
        placeholder="请选择名称,支持名称搜索"
        fetchOptions={onNameSearch}
        initialSearchKey={''}
      />
    </Form.Item>
    

    相关文章

      网友评论

          本文标题:React DebounceSelect 组件 自用

          本文链接:https://www.haomeiwen.com/subject/tvvgddtx.html