基于antd react实现分页加载的拉下选择器

这篇博客记录了作者在项目中实现基于antd的React分页加载选择器的过程,主要供个人日后查阅和分享。文章介绍了组件的初始化数据和功能实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

声明:网上类似这种的应该很多,我这里只是项目用到,自己记录一下,方便以后遇到cv代码

定义初始数据

interface PointOfSaleFormFiberInitialStateType {
  blocLevelList: CommonServersType.GetblocLevelListItem[]; // 列表
  blocLevelLoading: boolean; // 是否加载
  currPage: number; // 请求分页
  total: number; // 列表总量
  searchValue: string; // 输入框内容
}

const PointOfSaleFormFiberInitialState: PointOfSaleFormFiberInitialStateType = {
  blocLevelList: [],
  blocLevelLoading: false,
  currPage: 1,
  total: 0,
  searchValue: '',
};

// 防抖需要的变量
let searchFlag: any = null;

下面是组件功能


// 自定义的hook,功能类似setState
  const [state, setState] = useSetState(PointOfSaleFormFiberInitialState);

  const { blocLevelList, currPage, total, blocLevelLoading, searchValue } = state;


// 获取列表
  const getBlocLevelList = useCallback(
    (_props: { page: number; list: any[]; value?: string }): any => {
      // _props传入 分页, 现有列表,输入框内容
      const { page, list, value } = _props;
      // 当不是第一页切 列表数量大于等于总数时终止掉
      if (page !== 1 && list?.length >= total) {
        message.destroy();
        return message.warning('没有更多数据了');
      } else if (blocLevelLoading) {
        // 如果处于加载中也终止掉
        return;
      }
      // 请求,加载中
      setState({ blocLevelLoading: true });
      // 请求接口
      CommonServers.getblocLevelList({
        currPage: page,
        pageSize: 30,
        searchKey: value !== undefined ? value : searchValue,
        // 如果是上拉加载,_props的value可能为空,则需要使用state状态的输入框内容
      }).then(({ code, data }) => {
        if (code === 200) {
          // 合并列表数据,关闭加载中状态,当前分页修改,总数修改
          setState({
            blocLevelList: [...list, ...data?.list],
            blocLevelLoading: false,
            currPage: page,
            total: data?.totalCount,
          });
        }
      });
    },
    // callback监听 总数,是否加载中,输入框内容
    [total, blocLevelLoading, searchValue],
  );

  // 滚动事件
  const onPopupScroll = useCallback(
    (event) => {
      event.persist();
      const { target } = event;
      if (target.scrollTop + target.offsetHeight === target.scrollHeight) {
        // 调用加载数据,传入需求请求的分页
        getBlocLevelList({
          page: currPage + 1,
          list: blocLevelList,
        });
      }
    },
    [blocLevelList],
  );

  // 选择器输入框改变
  const onSearch = useCallback(
    (event) => {
      if (searchFlag) {
        clearTimeout(searchFlag);
      }
      // 防抖 0.5后请求数据,把分页重置回1,列表重置
      searchFlag = setTimeout(() => {
        setState({
          searchValue: event,
        });
        getBlocLevelList({
          page: 1,
          list: [],
          value: event,
        });
        clearTimeout(searchFlag);
      }, 500);
    },
    [blocLevelList],
  );


下面是dom内容

<Form.Item label="下拉框" name="blocLevelCodes">
  <Select
    placeholder="占位符"
    mode="multiple"
    onSearch={onSearch}
    onPopupScroll={onPopupScroll}
    filterOption={false}
    allowClear
  >
    {blocLevelList &&
      blocLevelList.map((item) => (
        <Option value={item?.groupCode} key={item?.groupCode}>
          {item?.groupName}
        </Option>
      ))}
    {blocLevelLoading && (
      <Option value="loading" disabled>
        <Spin>加载中</Spin>
      </Option>
    )}
  </Select>
</Form.Item>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值