<Select />组件支持懒加载、关键字查询(扩展搜索框)

63 阅读1分钟
import React, { useState, useRef, useCallback, useEffect } from 'react';
import { getSysUserByPage } from '@/services';
import { Button, Input, Select } from 'antd';
import { UNVMessageBox } from 'UNV-DESIGN';
const lodash = require('lodash');
const { cloneDeep } = lodash;

const { Option } = Select;

interface Props {
  disabled: boolean;
  setAllOptions: (data: any) => void;
  allOptions: any[];
  setCurrentSelect: (data: any) => void;
  currentSelect: any;
}
const SelectUser = (props: Props) => {
  const {
    disabled,
    allOptions,
    setAllOptions,
    setCurrentSelect,
    currentSelect
  } = props;

  console.log('allOptions11111111', allOptions);

  const [options, setOptions] = useState<any[]>([]);
  const [fetching, setFetching] = useState(false);
  const [page, setPage] = useState(1);
  const [searchValue, setSearchValue] = useState('');
  const [hasMore, setHasMore] = useState(true);

  const getData = async (searchKey: any, page: number) => {
    setFetching(true);
    const res = await getSysUserByPage({
      pageNum: page,
      pageSize: 10,
      nameSearchKey: searchKey
    });
    const newOptions = res.data.records;
    const oldAllList = cloneDeep(allOptions);
    const allList = [...oldAllList, ...newOptions];
    setAllOptions(removeDuplicates(allList, 'name'));
    if (newOptions.length > 0) {
      setOptions(newOptions);
    } else {
      UNVMessageBox.info('未查询到用户信息');
    }
    setFetching(false);
    setHasMore(newOptions.length > 0);
  };

  const removeDuplicates = (arr: any[], key: string) => {
    return arr.filter(
      (item: any, index: number, self: any) =>
        index === self.findIndex((t: any) => t[key] === item[key])
    );
  };

  const handleSearch = () => {
    if (searchValue) {
      setPage(1);
      getData(searchValue, 1);
    } else {
      setHasMore(true);
    }
  };

  const handleScroll = (e: any) => {
    const { scrollTop, scrollHeight, clientHeight } = e.target;
    if (scrollTop + clientHeight >= scrollHeight - 20 && !fetching && hasMore) {
      setPage(page + 1);
      getData(searchValue, page + 1);
    }
  };

  useEffect(() => {
    getData(searchValue, 1);
  }, []);

  // 处理键盘事件
  const handleKeyDown = useCallback(
    (e) => {
      e.stopPropagation();
      if (e.key === 'Enter') {
        handleSearch();
      }
    },
    [handleSearch]
  );

  console.log('currentSelect11111', currentSelect);

  return (
    <Select
      disabled={disabled}
      showSearch
      mode="multiple"
      notFoundContent={fetching ? <span>Loading...</span> : null}
      filterOption={false}
      onPopupScroll={handleScroll}
      style={{ width: '100%' }}
      onChange={(keys: any) => {
        setCurrentSelect(keys);
      }}
      value={currentSelect}
      dropdownRender={(menu) => {
        return (
          <>
            <div style={{ padding: '8px', display: 'flex' }}>
              <Input
                onKeyDown={handleKeyDown}
                allowClear
                onChange={(e) => {
                  e.stopPropagation();
                  setSearchValue(e.target.value);
                }}
                style={{ flex: 1, marginRight: 8 }}
                placeholder="输入关键词"
              />
              <Button type="primary" onClick={handleSearch}>
                搜索
              </Button>
            </div>
            {menu}
          </>
        );
      }}
    >
      {options.map((option: any) => (
        <Option key={option.name} value={option.name}>
          {option.name}
        </Option>
      ))}
    </Select>
  );
};

export default SelectUser;