ant design select 搜索同时支持输入和下拉选中

这个需求看着简单,但是实现起来走了不少弯路。
![在这里插入图片描述](https://img-blog.csdnimg.cn/74008ea8204c47e5b33ada2e82c56e26.png

1. 需求

  • 当输入关键词时,远程搜索内容,有返回则下拉展示,无返回也要展示当前输入的关键词(不能失去焦点后输入框就置空了),然后点击查询就会根据输入框中的值查询公司的相关信息,也就是会调用两个接口
  • 要支持防抖搜索
    ant design select 搜索同时支持输入和下拉选中_第1张图片

这里面就遇到了几个问题:

  1. 远程搜索的时候,有数据返回,但是下拉展示的仍然是无数据。。。
  2. 搜索输入框正常情况下只支持下拉选中,如果输入的内容查不到,那么在失去焦点的时候就置空输入框了,也就是没法保持输入内容。

2.解决

  1. 问题1是因为select默认对搜索内容进行了过滤,可以设置filterOptionfalsefilterOption是会过滤数据,当返回值包含输入值才会显示在下拉框中。
  2. 问题2就需要多个步骤去解决了,1是设置selectvalue,2是在搜索和失去焦点的时候再次set value,保证输入框不置空。

3.代码

import { Button, Form, Input, message, Select } from 'antd'
import { useState, useEffect } from 'react'
import { useForm } from 'antd/es/form/Form'
import pageService from './service'
const AddModal = (props) => {
  const [form] = useForm()
  const [loadingCompay, setLoadingCompay] = useState(false) //查询公司名
  const [loadingUnicode, setLoadingUnicode] = useState(false) //查询统一信用代码
  const [companyList, setCompanyList] = useState([]) //模糊企业搜索下拉
  const [keyword, setKeyword] = useState('') //模糊关键词

  // 防抖
  const debounce = (fn, delay = 1000) => {
    let timer: any = null
    // 闭包
    return function f(args) {
      if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
        timer = null
        fn.call(this, args)
      }, delay)
    }
  }
  
 // 模糊搜索
  const getCompany = async (e) => {
    if (!e) {
      return false
    }
    let params = {
      keyword: e,
    }
    let res = await pageService.getCompany(params)
    if (res?.msgCode === '000000') {
      setCompanyList(res.data || [])
    }
  }
   
  // 点击查询,通过公司名获取公司信息
  const getBasicInfo = (key) => {}

  return (
    <Form form={form} name="normal_login">
      <Button  loading={loadingCompay} type="primary" onClick={() => { getBasicInfo('enterCompanyName')}}>查询</Button>
 	  <Form.Item name="enterCompanyName" label="公司姓名:">
         <Select placeholder="请选择" showSearch value={keyword} className="enterCompanyName" 
             onSearch={debounce(function (value) {
                  // 模糊搜索获取公司名
                  getCompany(value)
              }, 700)}
             onChange={(val: any) => {
                 // 选中下拉时,也将下拉值作为输入框的值
                 setKeyword(val)
                 // 绑定值到表单上
                 form.setFieldsValue({ enterCompanyName: val })
             }}
             filterOption={false} //必须加这个,否则会对返回值进行筛选
             onBlur={(e: any) => {
                 // 当是选中值的时候,就没有e.target.value,所以需要通过原生获取节点的值
                 let value = e.target.value ||
                      document.getElementsByClassName('enterCompanyName')[0]
                        ?.querySelector('.ant-select-selection-item')?.innerText
                  // 再次设置关键词
                  setKeyword(value)
                  // 绑定值到表单上
                  form.setFieldsValue({ enterCompanyName: value })
              }}
                >{companyList.map((item: any, index) => (
                      <Select.Option key={index} value={item.name}>
                        {item.name}
                      </Select.Option>
                    ))}
             </Select>
         </Form.Item>
    </Form>
  )
}

你可能感兴趣的:(react,问题,BUG,javascript,react.js,前端)