Select 中的 MUI 对象默认值不显示但在选择对象时显示
MUI Object in Select default value not showing but shows when object selected
由于代码显示默认情况下选项具有“chosenValue”,但是我必须更改它才能在下拉列表中默认显示某些内容,否则下拉列表为空。当页面以默认值加载时如何显示“chosenValue”?
这是一个 codeandbok 示例: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>}
</>
);
}
您遇到的问题是对象比较仅在您比较完全相同的对象时才计算为真。(参见)
options.aviableValues[0] === options.chosenValue // false
要解决此问题,您可以告诉 Mui 应如何显式呈现选项对象。
<Select
// other props...
renderValue={(o) => o.label} // add this line
>
或者,您可以将选项状态拆分为 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
挂钩被调用。
Code Sandbox 中的工作示例
我已经在 Code Sandbox 中分叉了您的示例,并使用有效的实现对其进行了修改。我还包含了一个 Autocomplete
替代方案。
https://codesandbox.io/s/musing-dew-58frco
为什么 selected 选项没有显示
正如 Ivan 所说,您的 Select
组件未显示 selected 值的原因是因为 selected 值与中的值是不同的对象选项和 Select
组件要求对象严格相等 (===
).
例如,尽管这些对象看起来相同,但它们将无法通过严格的相等性检查。您可以在控制台中测试此示例,这将导致 false
.
{ fruit: "apple" } === { fruit: "apple" }
如何使用Select
使用 Select
的最简单方法是让您的值成为一个字符串,并且您的每个选项都有一个标签和值键(都是字符串)。标签是将显示在屏幕上的内容,值是选择选项时将 selected 的内容。
例如,对于您的选项,您可以:
const options = [
{ label: "Apple", color: "red", value: "apple" },
{ label: "Orange", color: "orange", value: "orange" },
{ label: "Pear", color: "green", value: "pear" }
];
与其将选项存储在状态中,不如将其作为状态之外的变量,因为它不会发生变化。
您只需保持 selected 值的状态,我称之为 fruit
。 apple
是水果的初始值。
const [fruit, setFruit] = useState("apple");
在您的 Select
组件中,将 fruit
分配给 value
道具并确保每个项目的 value
提供给 value
道具的 MenuItem
:
<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 函数。
defaultValue
不是必需的,只有在组件不受控制时才应使用。这是来自 Material UI docs:
The default value. Use when the component is not controlled.
我们的组件是受控组件,因为我们从状态(水果)提供价值并处理变化(setFruit)。
替代方法是使用自动完成 - 如果您希望 selected 项目作为对象
在上面的解释中,我使用的是字符串值,即 apple
、orange
和 pear
。如果您希望 selected 值改为对象,例如{ label: "Apple", color: "red", value: "apple" }
,那么可以用Material UI's Autocomplete.
我们有相同的选项:
const options = [
{ label: "Apple", color: "red", value: "apple" },
{ label: "Orange", color: "orange", value: "orange" },
{ label: "Pear", color: "green", value: "pear" }
];
但我们的州不一样:
const [fruit, setFruit] = useState({
label: "Apple",
color: "red",
value: "apple"
});
请注意,此处的初始状态必须与其中一个选项完全匹配。
Autocomplete
组件提供了一个 isOptionEqualToValue
道具,它将我们 select 编辑的值与我们可以 select 的选项进行比较,以确定它应该呈现哪个。我们要比较 selected 项和选项项的 value
键。如果相等,则显示匹配的选项。例如,如果 selected 项是 { label: "Apple", color: "red", value: "apple" }
并且有一个选项也是 { label: "Apple", color: "red", value: "apple" }
,因为它们的值相等("apple" === "apple" 为真),则“Apple”将显示为 selected.
现在将其与 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" />
)}
/>;
希望这对您有所帮助。
由于代码显示默认情况下选项具有“chosenValue”,但是我必须更改它才能在下拉列表中默认显示某些内容,否则下拉列表为空。当页面以默认值加载时如何显示“chosenValue”? 这是一个 codeandbok 示例: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>}
</>
);
}
您遇到的问题是对象比较仅在您比较完全相同的对象时才计算为真。(参见)
options.aviableValues[0] === options.chosenValue // false
要解决此问题,您可以告诉 Mui 应如何显式呈现选项对象。
<Select
// other props...
renderValue={(o) => o.label} // add this line
>
或者,您可以将选项状态拆分为 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
挂钩被调用。
Code Sandbox 中的工作示例
我已经在 Code Sandbox 中分叉了您的示例,并使用有效的实现对其进行了修改。我还包含了一个 Autocomplete
替代方案。
https://codesandbox.io/s/musing-dew-58frco
为什么 selected 选项没有显示
正如 Ivan 所说,您的 Select
组件未显示 selected 值的原因是因为 selected 值与中的值是不同的对象选项和 Select
组件要求对象严格相等 (===
).
例如,尽管这些对象看起来相同,但它们将无法通过严格的相等性检查。您可以在控制台中测试此示例,这将导致 false
.
{ fruit: "apple" } === { fruit: "apple" }
如何使用Select
使用 Select
的最简单方法是让您的值成为一个字符串,并且您的每个选项都有一个标签和值键(都是字符串)。标签是将显示在屏幕上的内容,值是选择选项时将 selected 的内容。
例如,对于您的选项,您可以:
const options = [
{ label: "Apple", color: "red", value: "apple" },
{ label: "Orange", color: "orange", value: "orange" },
{ label: "Pear", color: "green", value: "pear" }
];
与其将选项存储在状态中,不如将其作为状态之外的变量,因为它不会发生变化。
您只需保持 selected 值的状态,我称之为 fruit
。 apple
是水果的初始值。
const [fruit, setFruit] = useState("apple");
在您的 Select
组件中,将 fruit
分配给 value
道具并确保每个项目的 value
提供给 value
道具的 MenuItem
:
<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 函数。
defaultValue
不是必需的,只有在组件不受控制时才应使用。这是来自 Material UI docs:
The default value. Use when the component is not controlled.
我们的组件是受控组件,因为我们从状态(水果)提供价值并处理变化(setFruit)。
替代方法是使用自动完成 - 如果您希望 selected 项目作为对象
在上面的解释中,我使用的是字符串值,即 apple
、orange
和 pear
。如果您希望 selected 值改为对象,例如{ label: "Apple", color: "red", value: "apple" }
,那么可以用Material UI's Autocomplete.
我们有相同的选项:
const options = [
{ label: "Apple", color: "red", value: "apple" },
{ label: "Orange", color: "orange", value: "orange" },
{ label: "Pear", color: "green", value: "pear" }
];
但我们的州不一样:
const [fruit, setFruit] = useState({
label: "Apple",
color: "red",
value: "apple"
});
请注意,此处的初始状态必须与其中一个选项完全匹配。
Autocomplete
组件提供了一个 isOptionEqualToValue
道具,它将我们 select 编辑的值与我们可以 select 的选项进行比较,以确定它应该呈现哪个。我们要比较 selected 项和选项项的 value
键。如果相等,则显示匹配的选项。例如,如果 selected 项是 { label: "Apple", color: "red", value: "apple" }
并且有一个选项也是 { label: "Apple", color: "red", value: "apple" }
,因为它们的值相等("apple" === "apple" 为真),则“Apple”将显示为 selected.
现在将其与 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" />
)}
/>;
希望这对您有所帮助。