问题描述
我有一个Material UI选择框,当它们最初是选择的选项时,它们不应用选择.我创建了一个
I have a Material UI select box that is not applying the selections when they are initially selected options.I've created a Code Sandbox where you can see that the first two options that are initially specified are not selected in the select field, which produces a duplicate selection if any of those is selected again.
But everything works fine if the selectedOptions
variable is initially initialized as an empty array []
.
Is there any way to fix this without changing the type of the availableOptions
to an array of strings?
import React, { Component } from "react";
import MenuItem from "@material-ui/core/MenuItem";
import FormControl from "@material-ui/core/FormControl";
import ListItemText from "@material-ui/core/ListItemText";
import Select from "@material-ui/core/Select";
export default class renderFixedField extends Component {
state = {
availableOptions: [],
selectedOptions: []
};
componentWillMount = () => {
const availableOptions = [
{ friendly: "code1", combined: "[c1] - (code1)" },
{ friendly: "code2", combined: "[c2] - (code2)" },
{ friendly: "code3", combined: "[c3] - (code3)" },
{ friendly: "code4", combined: "[c4] - (code4)" }
];
const selectedOptions = [
{ friendly: "code1", combined: "[c1] - (code1)" },
{ friendly: "code2", combined: "[c2] - (code2)" }
];
this.setState({
availableOptions,
selectedOptions: selectedOptions
});
};
handleChange = (event, values) => {
const selectedOptions = event ? event.target.value : values;
this.setState({ selectedOptions });
};
menuItems = () => {
const { availableOptions } = this.state;
return availableOptions.map(optionName => {
return (
<MenuItem value={optionName}>
<ListItemText primary={optionName.friendly} />
</MenuItem>
);
});
};
render() {
const { selectedOptions } = this.state;
return (
<FormControl>
<Select
multiple
value={selectedOptions}
onChange={this.handleChange}
renderValue={() => selectedOptions.map(el => el.friendly).join(", ")}
children={this.menuItems()}
/>
</FormControl>
);
}
}
Here is the code that Select
uses to check if a selected value matches a MenuItem's value:
function areEqualValues(a, b) {
if (typeof b === 'object' && b !== null) {
return a === b;
}
return String(a) === String(b);
}
https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Select/SelectInput.js#L9
Though objects are supported as values, in order for two objects to match, they must be the exact same object (a === b
).
In your codesandbox example you have:
const defaultOptions = [
{ friendly: "code1", combined: "[c1] - (code1)" },
{ friendly: "code2", combined: "[c2] - (code2)" }
];
const availableOptions = [
{ friendly: "code1", combined: "[c1] - (code1)" },
{ friendly: "code2", combined: "[c2] - (code2)" },
{ friendly: "code3", combined: "[c3] - (code3)" },
{ friendly: "code4", combined: "[c4] - (code4)" }
];
That is 6 unique objects. The fact that the first two defaultOptions have equivalent content as the first two availableOptions is meaningless to the ===
check.
You can fix this by instead using the exact same objects such as the following:
const availableOptions = [
{ friendly: "code1", combined: "[c1] - (code1)" },
{ friendly: "code2", combined: "[c2] - (code2)" },
{ friendly: "code3", combined: "[c3] - (code3)" },
{ friendly: "code4", combined: "[c4] - (code4)" }
];
const defaultOptions = availableOptions.slice(0, 2);
这篇关于材质UI选择未应用默认选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!