You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-infinite-scroll-component与MUI Autocomplete滚动联动异常问题

问题:MUI Autocomplete结合InfiniteScroll时scrollableTarget未触发滚动事件

已正确配置InfiniteScroll的hasMore与next方法,但滚动MUI Autocomplete下拉列表时,滚动事件未触发,推测问题出在滚动目标设置上,组件代码如下:

<InfiniteScroll
      dataLength={patientData.length}
      next={getMorePatients}
      hasMore={hasMore}
      endMessage={<h4>End of List</h4>}
      scrollableTarget="patient-auto-complete"
    >
      <Autocomplete
        id="patient-auto-complete"
        options={patientData}
        value={patient}
        filterOptions={filterOptionsPatientList}
        onChange={handlePatientChange}
        renderOption={(props, option) => {
          return (
            <li {...props} key={option.id} value={option.id}>
              {(option.firstName === option.lastName
                ? option.firstName
                : option.firstName + " " + option.lastName
              ).replace(null, "")}
            </li>
          );
        }}
        renderInput={(params) => <TextField {...params} label="Patient" />}
        disabled={formMode === "edit_meeting"}
        sx={{
          borderBottom: errorPatient ? 2 : 0,
          borderColor: errorPatient ? "error.main" : null,
        }}
      />
    </InfiniteScroll>;

问题根源

MUI Autocomplete的下拉列表容器(Listbox)并非Autocomplete本身的DOM节点,而是通过Popper组件动态生成并挂载到body标签下的独立元素。你当前把scrollableTarget设为Autocomplete的id,实际上监听的是输入框所在容器的滚动,而非下拉列表的滚动,自然不会触发加载逻辑。

解决方案

方法1:通过ListboxProps绑定下拉列表的ref

使用useRef获取Autocomplete下拉列表的实际DOM元素,将其作为scrollableTarget传入InfiniteScroll(部分InfiniteScroll库支持直接传入DOM元素,若仅支持id,可给Listbox手动设置id)。

修改后的代码示例:

import { useRef } from 'react';
import InfiniteScroll from 'react-infinite-scroll-component';
import Autocomplete from '@mui/material/Autocomplete';
import TextField from '@mui/material/TextField';

// 其他组件逻辑
const listboxRef = useRef(null);

return (
  <>
    <Autocomplete
      id="patient-auto-complete"
      options={patientData}
      value={patient}
      filterOptions={filterOptionsPatientList}
      onChange={handlePatientChange}
      renderOption={(props, option) => {
        return (
          <li {...props} key={option.id} value={option.id}>
            {(option.firstName === option.lastName
              ? option.firstName
              : `${option.firstName} ${option.lastName}`
            ).replace(null, "")}
          </li>
        );
      }}
      renderInput={(params) => <TextField {...params} label="Patient" />}
      disabled={formMode === "edit_meeting"}
      sx={{
        borderBottom: errorPatient ? 2 : 0,
        borderColor: errorPatient ? "error.main" : null,
      }}
      // 给下拉列表绑定ref和自定义id
      ListboxProps={{
        ref: listboxRef,
        id: 'patient-autocomplete-listbox'
      }}
    />
    <InfiniteScroll
      dataLength={patientData.length}
      next={getMorePatients}
      hasMore={hasMore}
      endMessage={<h4>End of List</h4>}
      // 若库支持DOM元素则传ref.current,否则传自定义id
      scrollableTarget={listboxRef.current || 'patient-autocomplete-listbox'}
    />
  </>
);

方法2:使用useAutocomplete hook获取Listbox元素

通过MUI提供的useAutocomplete hook,可以直接获取内部的Listbox DOM节点,无需手动绑定ref:

import { useAutocomplete } from '@mui/material/Autocomplete';

// 其他组件逻辑
const { listboxRef } = useAutocomplete({
  options: patientData,
  value: patient,
  onChange: handlePatientChange,
  // 其他配置项
});

// 将listboxRef.current传给InfiniteScroll的scrollableTarget
<InfiniteScroll
  // 其他配置
  scrollableTarget={listboxRef.current}
/>

关键注意点

  • 必须确保InfiniteScroll监听的是下拉列表的滚动容器(即MUI Autocomplete的Listbox元素),而非Autocomplete的根节点。
  • 若InfiniteScroll仅支持id作为scrollableTarget,需给Listbox手动设置唯一id。
  • 保证dataLength对应已加载的patientData长度,next方法能正确触发数据加载并更新patientData。

内容的提问来源于stack exchange,提问作者Malinda Peiris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 06:05:08