MUI Autocomplete filterOptions过滤结果正确但仍展示全部选项如何解决
问题根源
这是MUI Autocomplete组件自定义过滤场景的常见踩坑点,核心原因有两个:
- 你的选项是嵌套数组结构,MUI内部默认的选项相等性判断为引用比较,当过滤后返回的元素引用和原始options元素存在差异(哪怕内容完全一致)时,内部渲染逻辑会错误回退到展示全量选项
- 你没有显式受控输入值
inputValue,内部状态同步异常也会导致过滤结果不生效,即使你在filterOptions里拿到了正确的输入值、返回了正确的过滤结果
解决方法
按以下步骤修改代码即可修复:
- 新增受控输入值的状态,同时把过滤逻辑提到组件外部,直接给
options传过滤后的数组,完全绕开filterOptions的内部兼容问题 - 新增
isOptionEqualToValue属性,显式指定选项相等的判断逻辑,避免引用比较导致的异常
修改后的完整代码如下:
// 新增受控输入值状态 const [inputValue, setInputValue] = useState(''); <Autocomplete // 直接传过滤后的options,去掉原来的filterOptions属性 options={allCountries.filter(option => { if (inputValue === "") return true; const query = inputValue.toLowerCase(); return `${option[1].name.toLowerCase()} (+${option[1].phone})`.includes(query); })} // 新增inputValue和onInputChange受控逻辑 inputValue={inputValue} onInputChange={(event, newInputValue) => { setInputValue(newInputValue); }} // 新增选项相等判断逻辑 isOptionEqualToValue={(option, value) => option[1].phone === value[1].phone} onChange={(event, newValue) => { if (!newValue || !newValue[1] || !newValue[1].phone) return; setPrefix(newValue[1].phone); }} value={allCountries.find( (nestedArray) => nestedArray[1].phone === prefix )} autoHighlight getOptionLabel={(option) => `+${option[1].phone}`} renderOption={(props, option) => ( <Box component="li" sx={{ "& > img": { mr: 2, flexShrink: 0 } }} {...props} > <img width="20" src={`https://flagcdn.com/w20/${option[0].toLowerCase()}.png`} /> {option[1].name} (+{option[1].phone}) </Box> )} renderInput={(params) => ( <TextField {...params} label="Prefix" inputProps={{ ...params.inputProps, }} /> )} />
如果仍然想保留filterOptions的写法,只需要添加上述isOptionEqualToValue属性即可生效,不需要修改其他逻辑。
内容的提问来源于stack exchange,提问作者Sordep
相关产品推荐
相关产品推荐

