繁体   English   中英

MUI Object in Select默认值不显示但选择object时显示

[英]MUI Object in Select default value not showing but shows when object selected

由于代码显示选项默认有一个“chosenValue”,但是我必须更改它以在下拉列表中默认显示某些内容或下拉列表为空。 当页面以默认值加载时如何显示“chosenValue”? 这是一个codesandbok示例: https://codesandbox.io/s/practical-noether-dwt52t?file=/src/App.js:0-1421

import "./styles.css";
import {
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  OutlinedInput
} from "@mui/material";
import { useState } from "react";
export default function App() {
  const [options, setOptions] = useState({
    chosenValue: {
      label: "apple",
      color: "green"
    },
    aviableValues: [
      { label: "apple", color: "red" },
      { label: "Orange", color: "Orange" },
      { label: "pear", color: "green" }
    ]
  });
  const handleContentChange = (event) => {
    setOptions((prevState) => ({
      ...prevState,
      chosenValue: event.target.value
    }));
  };
  return (
    <>
      {options.chosenValue && (
        <FormControl sx={{ mt: 2 }}>
          <InputLabel id="demo-simple-select-helper-label">Fruits</InputLabel>
          <Select
            labelId="demo-simple-select-label"
            id="demo-simple-select"
            value={options.chosenValue}
            onChange={(e) => handleContentChange(e)}
            input={<OutlinedInput label={options.chosenValue.label} />}
            fullWidth
          >
            {options.aviableValues.map((item) => {
              return (
                <MenuItem value={item} key={item}>
                  {item.label}
                </MenuItem>
              );
            })}
          </Select>
        </FormControl>
      )}
      {options.chosenValue && <p>{options.chosenValue.label}</p>}
    </>
  );
}

代码沙箱中的工作示例

我已经在 Code Sandbox 中分叉了您的示例,并使用有效的实现对其进行了修改。 我还包括了一个Autocomplete选项。

https://codesandbox.io/s/musing-dew-58frco

为什么选择的选项不显示

正如 Ivan 所说,您的Select组件未显示所选值的原因是因为所选值与选项中的值不同, object 并且Select组件要求对象严格相等( === )。

例如,尽管这些对象看起来相同,但它们将无法通过严格的相等性检查。 您可以在控制台中测试此示例,这将导致false

{ fruit: "apple" } === { fruit: "apple" } 

Select使用方法

使用Select的最简单方法是让您的值成为一个字符串,并且您的每个选项都有一个 label 和值键(两个字符串)。 label 是将显示在屏幕上的内容,值是选择选项时将选择的内容。

例如,对于您的选择,您可以:

const options = [
  { label: "Apple", color: "red", value: "apple" },
  { label: "Orange", color: "orange", value: "orange" },
  { label: "Pear", color: "green", value: "pear" }
];

与其将选项存储在 state 中,不如将其作为 state 之外的变量,因为它不会改变。

您只需要保留 state 作为所选值,我将其称为fruit apple是水果的初始值。

const [fruit, setFruit] = useState("apple");

在您的Select组件中,将fruit分配给value prop 并确保每个项目的value都提供给MenuItemvalue prop:

<Select
  labelId="demo-simple-select-label"
  id="demo-simple-select"
  value={fruit} // this is coming from state
  onChange={(e) => setFruit(e.target.value)} // we can setFruit directly here
  input={<OutlinedInput label="Hello" />}
  fullWidth
>
  {options.map((item) => {
    return (
      <MenuItem value={item.value} key={item.value}>
        {item.label}
      </MenuItem>
    );
  })}
</Select>

我们可以直接在onChange道具中设置水果,而不是单独的 handleChange function。

defaultValue不是必需的,只有在组件不受控制时才应使用。 这是来自Material UI 文档

默认值。 当组件不受控制时使用。

我们的组件是一个受控组件,因为我们提供 state(水果)的值并处理更改 (setFruit)。

替代方法是使用自动完成 - 如果您希望将所选项目作为 object

在上面的解释中,我使用的是字符串值,即appleorangepear 如果您希望选择的值改为对象,例如{ label: "Apple", color: "red", value: "apple" } ,那么您可以使用Material UI 的 Autocomplete

我们有相同的选择:

const options = [
  { label: "Apple", color: "red", value: "apple" },
  { label: "Orange", color: "orange", value: "orange" },
  { label: "Pear", color: "green", value: "pear" }
];

但是我们的 state 不一样:

const [fruit, setFruit] = useState({
  label: "Apple",
  color: "red",
  value: "apple"
});

请注意,此处的初始 state 必须与其中一个选项完全匹配。

Autocomplete组件提供了一个isOptionEqualToValue道具,它将我们选择的值与我们可以 select 从中确定它应该呈现的选项进行比较。 我们要比较所选项目和选项项目的value键。 如果相等,则显示匹配的选项。 例如,如果所选项目是{ label: "Apple", color: "red", value: "apple" }并且有一个选项也是{ label: "Apple", color: "red", value: "apple" } ,因为它们的值相等("apple" === "apple" 为真),那么 "Apple" 将显示为选中状态。

现在将它与Autocomplete组件放在一起:

<Autocomplete
  options={options}
  value={fruit}
  isOptionEqualToValue={(option, value) => option.value === value.value}
  onChange={(event, newValue) => {
    setFruit(newValue);
  }}
  renderInput={(params) => (
    <TextField {...params} label="Fruits" variant="standard" />
  )}
/>;

希望这可以帮助。

您遇到的问题是,如果您比较完全相同的 object ,则 object 比较只会评估为真。(请参阅https://stackoverflow.com/a/11705017/18920728

options.aviableValues[0] === options.chosenValue  // false

要解决此问题,您可以告诉 Mui 选项 object 应该如何显式呈现。

<Select
  // other props...
  renderValue={(o) => o.label}  // add this line
>

或者,您可以将选项 state 拆分为 2 个状态:

const [options] = useState([
  { label: "apple", color: "red" },
  { label: "Orange", color: "Orange" },
  { label: "pear", color: "green" }
]);
const [selected, setSelected] = useState(options[0]);

...

<Select
  ...
  value={selected}
  ...
>

请注意,由于您控制的是 select 组件,因此无需在<Select>中指定default属性,默认值已在调用useState钩子时指定为默认值 state。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM