Выбор пользовательского интерфейса материала не применяет выбор по умолчанию - PullRequest
1 голос
/ 19 июня 2019

У меня есть поле выбора 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 Ответ

1 голос
/ 19 июня 2019

Вот код, который 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

...