材质UI选择未应用默认选择

材质UI选择未应用默认选择

本文介绍了材质UI选择未应用默认选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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选择未应用默认选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 02:32