Reputation: 1192
I'm trying to use a controlled react MUI Select
element with a few options, but the initial value must be empty (no initial value - empty selection). This sounds like a pretty common behavior. I do not want one of the options selected by default.
From what I read in case the value is a string you should use ''
instead of undefined as a default value. However in my case the options are objects, so the only way is to set it as undefined
or null
.
Here is a link to an example. Notice the warning when it first renders:
You have provided an out-of-range value undefined for the select component.
And the error when choosing one of the options:
A component is changing the uncontrolled value state of Select to be controlled. Elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled Select element for the lifetime of the component. The nature of the state is determined during the first render. It's considered controlled if the value is not undefined.
Any idea how this should be done?
Upvotes: 2
Views: 11785
Reputation: 21
If you want to keep the value of the options as an object, you can do it like so. I must admit It doesn't look very fancy.
function App() {
const [item, setItem] = React.useState("");
return (
<Select
value={item?.type ? JSON.stringify(item.type) : ""}
displayEmpty
onChange={(event) => {
console.log(`changed: ${JSON.stringify(event.target.value)}`);
setItem({ ...item, type: JSON.parse(event.target.value) });
}}
>
{types?.map((type) => (
<MenuItem value={JSON.stringify(type)} key={type.id}>
{type?.name ? type.name : ""}
</MenuItem>
)) ?? []}
</Select>
);
}
I suggest keeping the value as the id property of each object. This would be the approach:
function App() {
const [item, setItem] = React.useState('');
return (
<Select
value={item}
displayEmpty
onChange={(e) => {
setItem(e.target.value);
}}
>
{types?.map((type) => (
<MenuItem value={type.id} key={type.id}>{type.name ?? ""}</MenuItem>
)) ?? []}
</Select>
);
}
You don't really need the renderValue prop. Also, keep in mind that you should add a key to each option.
Upvotes: 1