Im' new to react from angularjs, using material-ui for a project and I can't get the select component to work like a select component. Basically I want to populate the dropdown with an array of objects and do something with the selected object once a selection is made by the user. I've been running into a bunch of problems, the most recent is that I can't figure out how to set a default starting value when the component loads and I can't see the selected option in the GUI. I'm able to set the state and log it out to the console you just can't see it in the select component. Also, what is the difference between @material-ui/core and material-ui. Are they different libraries, different versions of the same library?
class HomePage extends React.Component {
constructor(props) {
super();
this.reportSelected = this.reportSelected.bind(this);
this.state = {
report: "report1"
};
}
static propTypes = {
classes: PropTypes.object
};
reports = [
{
name: "report1"
},
{
name: "report2"
},
{
name: "report3"
}
];
reportSelected = event => {
this.setState((prevState) => {
return {
report: event.target.value
}
}, console.log(this.state))
};
render() {
const { classes, headerTitle } = this.props;
return (
<div className={classes.homePage}>
<HeaderTitle title="Home" />
<Helmet>
<title>{headerTitle}</title>
</Helmet>
<form>
<FormControl className={classes.reportsDropdown}>
<InputLabel htmlFor="reports">Reports</InputLabel>
<Select
value={this.state.report}
onChange={this.reportSelected}
>
{this.reports.map(report => (
<MenuItem value={report.name} key={report.name}>
{report.name}
</MenuItem>
))}
</Select>
</FormControl>
</form>
</div>
);
}
}
UPDATE:
The following code works as expected,
class HomePage extends React.Component {
constructor(props) {
super();
this.reportSelected = this.reportSelected.bind(this);
this.state = {
report: "report1"
};
}
static propTypes = {
classes: PropTypes.object
};
reports = [
{
name: "report1"
},
{
name: "report2"
},
{
name: "report3"
}
];
reportSelected = event => {
this.setState(() => {
return {
report: event.target.value
}
})
};
render() {
const { classes, headerTitle } = this.props;
return (
<div className={classes.homePage}>
<HeaderTitle title="Home" />
<Helmet>
<title>{headerTitle}</title>
</Helmet>
<form>
<FormControl className={classes.reportsDropdown}>
<InputLabel htmlFor="reports">Reports</InputLabel>
<Select
value={this.state.report}
onChange={this.reportSelected}
>
{this.reports.map(report => (
<MenuItem value={report.name} key={report.name}>
{report.name}
</MenuItem>
))}
</Select>
</FormControl>
</form>
</div>
);
}
}
In this first way is we can save some lines of code only working directly with the TextField component and add the select prop to made our input work like an select. Now through the prop inputProps that Material UI provide to us we can add prop directly to the select input component. Magic!
This is necessary to avoid a warning: If defaultValue is set to undefined, React assumes this select component is “uncontrolled” and subsequently when it is set, it switches to “controlled”. RHF supports both controlled and uncontrolled components, but Material UI requires the component to be controlled.
The most advantage of use React Hook Form is to get all the benefits of work with uncontrolled components in forms like skip re-rendering and faster mount. But there are some limitations in use some components that are created to work internally like a controlled, this is the case of component Select of Material UI.
The errors you are getting are about how the material-ui package uses ref forwarding. The Select component expects its children to be something which accepts a forwarded ref, and your List component doesn't. I think that all you need to do is move the mapping inside of the Select rather than defining it as a separate function component.
I would imagine the problem is that the initial selected value must match a value of an item in the select.
In the code sample you are using the name property this.reports[0].name
as the initial value, but your menu items use the object itself for the value, i.e. value={report}
.
Either use the name property for the value of the menu items or use this.reports[0]
as your initial value and see if that works.
As for your second question, material-ui is the previous version of the library (the 0.xx series). @material-ui is the latest and greatest 1.11 version.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With