英文:
MUI Select - handling duplicate option in dropdown
问题
我正在使用 MUI v5,并且有两个选项具有重复的名称。当我使用 Select 组件选择它们时,两者都会被选中。
我该如何在 MUI v5 中处理这个问题?
import * as React from "react";
import OutlinedInput from "@mui/material/OutlinedInput";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import ListItemText from "@mui/material/ListItemText";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import Checkbox from "@mui/material/Checkbox";
const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250
}
}
};
const namesObj = [
{
id: 1,
name: "Oliver Hansen"
},
{
id: 2,
name: "Van Henry"
},
{
id: 3,
name: "April Tucker"
},
{
id: 4,
name: "April Tucker"
}
];
export default function MultipleSelectCheckmarks() {
const [personName, setPersonName] = React.useState<string[]>([]);
console.log("personName: ", personName);
const handleChange = (event: SelectChangeEvent<typeof personName>) => {
const {
target: { value }
} = event;
setPersonName(
// On autofill we get a stringified value.
typeof value === "string" ? value.split(",") : value
);
};
return (
<div>
<FormControl sx={{ m: 1, width: 300 }}>
<InputLabel id="demo-multiple-checkbox-label">Tag</InputLabel>
<Select
labelId="demo-multiple-checkbox-label"
id="demo-multiple-checkbox"
multiple
value={personName}
onChange={handleChange}
input={<OutlinedInput label="Tag" />}
renderValue={(selected) => selected.join(", ")}
MenuProps={MenuProps}
>
{namesObj.map((name) => (
<MenuItem key={name.id} value={name.name}>
<Checkbox checked={personName.indexOf(name.name) > -1} />
<ListItemText primary={name.name} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}
英文:
I am using MUI v5 and I have two options which have a duplicate name. When I select them using the Select component, both are selected.
How would I handle this in MUI v5?
import * as React from "react";
import OutlinedInput from "@mui/material/OutlinedInput";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import ListItemText from "@mui/material/ListItemText";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import Checkbox from "@mui/material/Checkbox";
const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250
}
}
};
const namesObj = [
{
id: 1,
name: "Oliver Hansen"
},
{
id: 2,
name: "Van Henry"
},
{
id: 3,
name: "April Tucker"
},
{
id: 4,
name: "April Tucker"
}
];
export default function MultipleSelectCheckmarks() {
const [personName, setPersonName] = React.useState<string[]>([]);
console.log("personName: ", personName);
const handleChange = (event: SelectChangeEvent<typeof personName>) => {
const {
target: { value }
} = event;
setPersonName(
// On autofill we get a stringified value.
typeof value === "string" ? value.split(",") : value
);
};
return (
<div>
<FormControl sx={{ m: 1, width: 300 }}>
<InputLabel id="demo-multiple-checkbox-label">Tag</InputLabel>
<Select
labelId="demo-multiple-checkbox-label"
id="demo-multiple-checkbox"
multiple
value={personName}
onChange={handleChange}
input={<OutlinedInput label="Tag" />}
renderValue={(selected) => selected.join(", ")}
MenuProps={MenuProps}
>
{namesObj.map((name) => (
<MenuItem key={name.id} value={name.name}>
<Checkbox checked={personName.indexOf(name.name) > -1} />
<ListItemText primary={name.name} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}
https://codesandbox.io/s/priceless-spence-n79nhd?file=/demo.tsx:0-2005
答案1
得分: 2
MUI使用MenuItem组件的value属性来确定哪些选项已被选择。如果两个选项具有相同的value值,则当点击其中一个选项时,它们都将被选中。
一个可能的解决方案是,使用namesObj
数组的id
属性作为MenuItem
组件的value值,而不是使用name
属性。这样,每个选项都将有一个唯一的value值,可用于识别它。例如:
export default function MultipleSelectCheckmarks() {
const [personName, setPersonName] = React.useState<number[]>([]);
console.log("personName: ", personName);
const handleChange = (event: SelectChangeEvent<typeof personName>) => {
const {
target: { value }
} = event;
setPersonName(
typeof value === "string"
? value.split(",").map((item) => Number(item))
: value
);
};
return (
<div>
<FormControl sx={{ m: 1, width: 300 }}>
<InputLabel id="demo-multiple-checkbox-label">Tag</InputLabel>
<Select
multiple
value={personName}
onChange={handleChange}
input={<OutlinedInput label="Tag" />}
renderValue={(selected) =>
selected
.map((id) => namesObj.find((name) => name.id === id).name)
.join(", ")
}
MenuProps={MenuProps}
>
{namesObj.map((name) => (
<MenuItem key={name.id} value={name.id}>
<Checkbox checked={personName.indexOf(name.id) > -1} />
<ListItemText primary={name.name} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}
英文:
MUI uses the value property of the MenuItem component to determine which options are selected. If two options have the same value, they will both be selected when one of them is clicked.
One possible solution is to use the id
property of the namesObj
array as the value of the MenuItem
component, instead of the name
property. This way, each option will have a unique value that can be used to identify it. For example:
export default function MultipleSelectCheckmarks() {
const [personName, setPersonName] = React.useState<number[]>([]);
console.log("personName: ", personName);
const handleChange = (event: SelectChangeEvent<typeof personName>) => {
const {
target: { value }
} = event;
setPersonName(
typeof value === "string"
? value.split(",").map((item) => Number(item))
: value
);
};
return (
<div>
<FormControl sx={{ m: 1, width: 300 }}>
<InputLabel id="demo-multiple-checkbox-label">Tag</InputLabel>
<Select
multiple
value={personName}
onChange={handleChange}
input={<OutlinedInput label="Tag" />}
renderValue={(selected) =>
selected
.map((id) => namesObj.find((name) => name.id === id).name)
.join(", ")
}
MenuProps={MenuProps}
>
{namesObj.map((name) => (
<MenuItem key={name.id} value={name.id}>
<Checkbox checked={personName.indexOf(name.id) > -1} />
<ListItemText primary={name.name} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论