Antd3中的受控表单组件封装实例

展示效果

要求:左边是可以可以搜索的select,搜索结果点击搜索按钮执行搜索操作;

代码实现

import React, { memo, useState } from 'react'
import { Button, Input, Select } from 'antd'
import _ from 'lodash'
import { apiSearchUser } from '@/pages/User/CourseUser/api'
import { IUserItem } from '@/pages/User/CourseUser/interface'

interface IProps {
  // value和onChange是受控组件必须用的属性
  value?: string;
  onChange?: (value: string) => void;
  onSearch?: (value: string) => void;
}

const NickSearchBox = ({ value = '', onChange, onSearch }: IProps, ref: React.Ref<any>) => {
  const [val, setVal] = useState<string>(value)
  // 下拉列表
  const [list, setList] = useState<IUserItem[]>([])
  // 触发下拉框搜索
  const handleSearch = _.debounce(async (value: string) => {
    const resp = await apiSearchUser({
      nick: value,
      page: 1,
      limit: 30,
    })
    if (resp.status === 'OK') {
      setList(resp.data)
    } else {
      setList([])
    }
  }, 500)

  // 修改存储
  const handleChange = (val: string) => {
    setVal(val)
    onChange && onChange(val)
  }

  // 搜搜
  const handleClick = () => {
    onSearch && onSearch(val)
  }

  return (
    <Input.Group compact>
      <Select
        showSearch
        value={val || undefined}
        ref={ref}
        style={{ width: 160 }}
        placeholder="昵称模糊搜索"
        defaultActiveFirstOption={false}
        filterOption={false}
        onSearch={handleSearch}
        onChange={handleChange}
        notFoundContent={null}
        showArrow={false}>
        {
          list.map(item => (
            <Select.Option key={item.id} value={item.nick}>{item.nick}</Select.Option>
          ))
        }
      </Select>
      <Button icon="search" onClick={() => handleClick()} />
    </Input.Group>
  )
}

export default memo(React.forwardRef(NickSearchBox))

注意事项

1、要转发ref,必须要是使用React.forwardRef将函数组件包裹(Antd3),否则报错;
2、要放在表单(Form)组件中,需要定义value和onChange属性并且设置为可选属性;
3、组件的输入结果保存在当前组件中;
4、Select组件中设置了showSearch后导致placeholder不显示,需要将value设置到undefined即可;

留下回复