如何实现MUI Autocomplete选中后将选项从下拉列表移除且不修改原数据
问题根因
你的代码无法实现过滤已选选项的效果,核心是两个逻辑错误:
movies数组存储的是电影标题(字符串类型),但你在filterOptions中直接用电影对象和字符串数组做includes判断,不同类型的值永远不可能匹配,过滤逻辑完全没有生效- 不需要用
key强制重渲染Autocomplete组件,只要每次选中后清空组件的输入值即可
修正后代码(兼容MUI5)
import React, { useState } from "react"; import TextField from "@mui/material/TextField"; import Autocomplete from "@mui/material/Autocomplete"; import List from "@mui/material/List"; import ListItem from "@mui/material/ListItem"; import ListItemText from "@mui/material/ListItemText"; import HighlightOffIcon from "@mui/icons-material/HighlightOff"; import IconButton from "@mui/material/IconButton"; export default function Playground() { const [movies, setMovies] = useState([]); // 存储Autocomplete的输入值,选中后清空 const [inputValue, setInputValue] = useState(""); return ( <div style={{ width: 300 }}> <Autocomplete options={top100Films} getOptionLabel={(option) => option.title} inputValue={inputValue} onInputChange={(_, newInputValue) => setInputValue(newInputValue)} filterOptions={(options, state) => { // 先做关键词过滤,再过滤掉已选中的电影 return options .filter(option => option.title.includes(state.inputValue)) // 用title判断是否已选中 .filter(movie => !movies.includes(movie.title)); }} renderInput={(params) => ( <TextField {...params} label="movies" margin="normal" /> )} onChange={(e, movie) => { if (movie) { setMovies([...movies, movie.title]); // 选中后清空输入 setInputValue(""); } }} /> <List> {movies.map((movie) => ( <ListItem key={movie}> <ListItemText primary={movie} /> <IconButton aria-label="delete" onClick={() => { setMovies(movies.filter((m) => m !== movie)); }} > <HighlightOffIcon /> </IconButton> </ListItem> ))} </List> </div> ); } const top100Films = [ { title: "The Shawshank Redemption", year: 1994 }, { title: "The Godfather", year: 1972 }, { title: "The Godfather: Part II", year: 1974 }, { title: "The Dark Knight", year: 2008 }, ];
MUI5适配说明
如果你已经升级到MUI5,只需要把原来@material-ui/开头的导入路径替换为@mui/即可,Autocomplete组件的filterOptions属性用法和旧版完全兼容,不需要额外修改逻辑。
内容的提问来源于stack exchange,提问作者wolf_math
相关产品推荐
相关产品推荐

