材质用户界面选择未应用默认选择

时间:2019-06-19 12:57:06

标签: reactjs material-ui

我有一个Material UI选择框,当它们是最初选择的选项时,它不应用选择。 我创建了一个Code Sandbox,您可以看到在选择字段中未选择最初指定的前两个选项,如果再次选择其中任何一个,则会产生重复的选择。
但是,如果selectedOptions变量最初初始化为空数组[],一切都会正常。
有什么方法可以解决此问题而无需将availableOptions的类型更改为字符串数组?

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

1 个答案:

答案 0 :(得分:1)

这是Select用于检查所选值是否与MenuItem的值匹配的代码:

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

尽管支持将对象作为值,但要使两个对象匹配,它们必须是完全相同的对象a === b)。

在您的代码和框示例中,您有:

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)" }
];

那是6个唯一的对象。前两个defaultOptions具有与前两个availableOptions相同的内容,这对===检查毫无意义。

您可以改用完全相同的对象来解决此问题,例如:

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

Edit default options for Select