6
votes

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>
    );
  }
}
1

1 Answers

7
votes

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.