美文网首页
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 组件渲染过程---自用

    组件的生命周期 getDefaultProps : 初始化propsconstructor:可以初始化state ...

  • React基础

    React包含react元素和react组件 react元素 react组件 react组件分为函数组件和类组件 ...

  • 组件

    组件是React的基石,所有的React应用程序都是基于组件的。React组件,可以通过React.createC...

  • ReactNative学习笔记(三)Hello World!

    React Native 看起来很像 React,但React Native的基础组件是原生组件 不是web组件。...

  • react子组件向父组件传值

    相关资料:react 父组件怎么获取子组件的这个值React组件间信息传递方式react同级组件之间传值 • 父...

  • React 进阶二 组件详解

    React组件 React的组件大概分为俩部分,无状态组件和有状态组件 无状态组件。下面React官网中定义的一个...

  • 2、react基础介绍

    React理念 划分组件边界的原则 React组件的数据种类 React组件的声明周期 组件的划分 高内聚 低耦合...

  • React概念图

    React概念图 React组件生命周期概念图 参考文档:React入门教程 组件生命周期React:组件生命周期...

  • react16.3-jest

    功能组件和UI组件 react-antd 命名 react 规定组件开头都为大写,所以如果react项目如果用an...

  • 如何创建React组件并发布到npm?

    实现步骤: 创建React组件项目; 创建测试项目并引用组件; 发布React组件到npm上; 一、创建React...

网友评论

      本文标题:React DebounceSelect 组件 自用

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