Formik与MUI Autocomplete多选组件:搜索不高亮、可重复选择问题
问题描述
- 结合Formik与MUI Autocomplete多选组件时,输入“Pencil”搜索,匹配的选项无法高亮显示
- 已选中的选项仍可被重复点击选择
- 期望效果:支持正常单选/多选,选中项的复选框自动勾选,同时对应选项高亮
解决方案
1. 修复搜索匹配高亮问题
你设置的filterOptions={(x) => x}完全禁用了MUI内置的过滤与高亮逻辑,导致搜索时无法自动高亮匹配项。由于选项是通过接口根据搜索词返回的过滤结果,只需保留MUI的高亮逻辑,不对选项二次过滤即可:
- 替换
filterOptions={(x) => x}为filterOptions={(options, state) => options},既保留接口返回的选项列表,又能启用内置的高亮功能。
2. 修复重复选择问题
当前renderOption未正确使用组件传入的selected参数,且Autocomplete无法正确识别已选中的选项:
- 添加
isOptionEqualToValue属性,基于id判断选项与选中值是否相等,让组件正确维护选中状态 - 在
renderOption中,将selected参数传入Checkbox的checked属性,结合Formik的values确保状态同步
修改后的代码
const TestAutocomplete = ({ field, form: { touched, errors, setFieldValue, values }, ...props }) => { const [inputValue, setInputValue] = useState(""); const debouncedInputValue = useDebounceValue(inputValue, 500); const { data: response, isLoading } = useFetchSubledgersQuery({ pageNumber: 0, pageSize: 50, search: debouncedInputValue, }); const handleChange = (_, newSelectedValues, reason) => { if (reason === "clear") { setFieldValue(field.name, []); return; } setFieldValue(field.name, newSelectedValues); }; const handleInputChange = (_, newInputValue) => { setInputValue(newInputValue); }; return ( <Autocomplete {...field} multiple getOptionLabel={(option) => typeof option === "string" ? option : option?.name || "" } filterOptions={(options, state) => options} options={response || []} autoComplete includeInputInList fullWidth noOptionsText={isLoading ? "Loading..." : "No data"} onChange={handleChange} inputValue={inputValue} onInputChange={handleInputChange} isOptionEqualToValue={(option, value) => option.id === value.id} renderInput={(params) => ( <TextField {...params} {...props} error={touched[field.name] && errors[field.name] ? true : false} helperText={ touched[field.name] && errors[field.name] && String(errors[field.name]) } /> )} renderOption={(props, option, { selected }) => ( <li {...props}> <Checkbox icon={icon} checkedIcon={checkedIcon} style={{ marginRight: 8 }} checked={selected || values?.[field.name]?.some( (selectedValue) => selectedValue.id === option.id )} /> {option?.name} </li> )} renderTags={(value, getTagProps) => value.map((option, index) => ( <Chip key={option.id} label={option.name} {...getTagProps({ index })} /> )) } /> ); };
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

