使用MUI的ListboxComponent时Autocomplete的onChange不触发
Material UI Autocomplete + react-window 虚拟滚动 onChange 失效解决
问题
用Material UI的Autocomplete组件搭配react-window的FixedSizeList自定义ListboxComponent后,onChange事件完全触发不了,给ListItem加onClick也没用。但去掉自定义的ListboxComponent后一切正常,怀疑是ref传递的问题。
原代码
<Autocomplete options={options} fullWidth renderInput={renderOptionValue} onChange={(e, value) => { // @ts-ignore console.log(e.target, value.title); }} getOptionLabel={(option) => getUserFullName(option)} PopperComponent={(props) => <S.DropDownPopper {...props} />} ListboxComponent={() => ( <FixedSizeList height={400} itemCount={options.length} itemData={[...options]} itemSize={36} overscanCount={5} width="100%" > {(props) => <ListItem {...props} />} </FixedSizeList> )} />
解决方法
核心问题
你没把Autocomplete传给ListboxComponent的关键props(包括ref、事件处理、角色属性等)传递给FixedSizeList,同时自定义的ListItem也没绑定Autocomplete内部的选择逻辑,导致组件无法识别点击/选择动作。
修改步骤
- 用forwardRef封装自定义Listbox
必须把Autocomplete传入的ref传递给FixedSizeList,这样组件才能正确管理焦点和交互。 - 复用Autocomplete默认的列表项
不要自己写ListItem,直接用Autocomplete生成的默认列表项,避免丢失选择逻辑。
修改后完整代码
import { useAutocomplete } from '@mui/material/Autocomplete'; import FixedSizeList from 'react-window/FixedSizeList'; import React from 'react'; // 自定义虚拟滚动列表容器 const CustomListbox = React.forwardRef((props, ref) => { const { children, ...restProps } = props; const { options } = useAutocomplete(); return ( <FixedSizeList ref={ref} itemCount={options.length} itemSize={36} height={400} width="100%" overscanCount={5} {...restProps} // 传递Autocomplete的Listbox属性 > {({ index, style }) => { // 获取Autocomplete默认生成的对应索引列表项 const defaultListItem = React.Children.toArray(children)[index]; // 克隆项并添加虚拟滚动的样式 return React.cloneElement(defaultListItem, { style }); }} </FixedSizeList> ); }); // 使用修改后的Autocomplete <Autocomplete options={options} fullWidth renderInput={renderOptionValue} onChange={(e, value) => { // @ts-ignore console.log(e.target, value.title); }} getOptionLabel={(option) => getUserFullName(option)} PopperComponent={(props) => <S.DropDownPopper {...props} />} ListboxComponent={CustomListbox} // 替换为自定义容器 />
说明
- 传递
restProps给FixedSizeList,确保Autocomplete的键盘导航、焦点管理等逻辑正常工作。 - 复用默认列表项,自动带上了Autocomplete的点击选择逻辑,无需手动绑定onClick。
内容的提问来源于stack exchange,提问作者Rostyk
相关产品推荐
相关产品推荐

