i've a MaterialUI Select code, and i'm handling the value parameter dynamically. My problem is, when i set any value, it says always it's out of range, even showing the value in the valid values.
SelectInput.js:291 Material-UI: you have provided an out-of-range value `100001,250000` for the select (name="followers") component. Consider providing a value that matches one of the available options or ''. The available values are `0,50000`, `50001,100000`, `100001,250000`, `250001,500000`, `500001,750000`, `750001,9007199254740991`. (anonymous) @ SelectInput.js:291 And this is my code simplified:
const followers = [ { '0-50k': [0, 50000] }, { '50k-100k': [50001, 100000] }, { '100k-250k': [100001, 250000] }, { '250k-500k': [250001, 500000] }, { '500k-750k': [500001, 750000] }, { '+1M': [750001, Number.MAX_SAFE_INTEGER] }, ]; <div className={classes.formGroup}> <InputLabel>Followers</InputLabel> <Select className={classes.field} fullWidth labelId="followersL" margin="dense" displayEmpty name="followers" onChange={(event) => setValue(event.target.value)} //I've updated the sate with the new value value={ filters.basicInfo.followers ? value : '' } variant="outlined" > {followers.map((element) => ( <MenuItem value={element[Object.keys(element)]} key={Object.keys(element)[0]} > {Object.keys(element)[0]} </MenuItem> ))} </Select> </div> As you can see in the message, the value selected 100001,250000 it's inside the range examples 100001,250000
Where is the problem?
29 Answers
add this defaultValue = "" like this <Select ... defaultValue="" >
5This advice may be useful for others: If the value for Select element is object, it should be the exact instance of the object from the list of Options. For example:
const [test, setTest] = useState(""); //list of options for Material UI select const testOptions = [ {name: "123"}, {name: "456"}, {name: "769"}, ]; //let's try to change value to {name: "123"} using JS setTest(testOptions[0]); // everything is OK setTest({name: "123"}); // Error! You provided out of range value! 3Stringifying your value will get this to work.
element[Object.keys(element)] + ""} If you needed it to be in its original array format before sending the result to your server you could use a function like this to do this
const strToArr = str => str.split(',').map(item => Number(item)) In my code here I have used your provided example and been able to replicate your error. But Stringifying the value removes the error and gets it to work as expected.
import React from "react"; import { makeStyles } from "@material-ui/core/styles"; import InputLabel from "@material-ui/core/InputLabel"; import MenuItem from "@material-ui/core/MenuItem"; import Select from "@material-ui/core/Select"; const useStyles = makeStyles(theme => ({ formControl: { margin: theme.spacing(1), minWidth: 120 }, selectEmpty: { marginTop: theme.spacing(2) } })); export default function SimpleSelect() { const classes = useStyles(); const followers = [ { "0-50k": [0, 50000] }, { "50k-100k": [50001, 100000] }, { "100k-250k": [100001, 250000] }, { "250k-500k": [250001, 500000] }, { "500k-750k": [500001, 750000] }, { "+1M": [750001, Number.MAX_SAFE_INTEGER] } ]; const [value, setValue] = React.useState(""); const handleChange = event => setValue(event.target.value); return ( <div> <p>value - {value}</p> <div className={classes.formGroup}> <InputLabel>Followers</InputLabel> <Select className={classes.field} fullWidth labelId="followersL" margin="dense" displayEmpty name="followers" onChange={handleChange} value={value} variant="outlined" > {followers.map(element => ( <MenuItem value={element[Object.keys(element)] + ""} key={Object.keys(element)[0]} > {Object.keys(element)[0]} </MenuItem> ))} </Select> </div> </div> ); }I ran into the same problem (you have provided an out-of-range value) when using a number state with a default value of -1:
const [selectedAccountId, setSelectedAccountId] = useState<number>(-1); The solution to this problem was to assign an empty string for the value property in Material's UI Select component instead of using the default value of -1:
value={selectedAccountId === -1 ? '' : selectedAccountId} Full component example:
<FormControl fullWidth> <InputLabel>Account</InputLabel> <Select value={selectedAccountId === -1 ? '' : selectedAccountId} onChange={event => { setSelectedAccountId(Number(event.target.value)); }}> {allAccounts.map((account, index) => ( <MenuItem key={index} value={account.id}> {account.exchange} ({account.id}) </MenuItem> ))} </Select> </FormControl> From some research, what I've come to understand to be the reason for this warning, in my case, is the MUI Select was trying to map over a list of options that were not available on the first render as the list was coming from Axios response.
I made a component named Dropdown that renders the MUI Select component. I was providing it four props:
options: the list of options,initialValue: the default value as I had different default values for different instances of theDropdowncomponent that were not the first item of theoptionslist always
... and 2 other props that are not scoped for this discussion.
So, for each instance of the Dropdown component, I had to check whether the options list has any data, and only then render it. And this is what removed the warning from the console. To give a glimpse of what I did:
{viewsData.length > 0 && ( <Dropdown options={viewsData} initialValue={7} {...otherProps} /> )} This was bugging me for a long time. Hopefully this will help someone.
1It's because value should be '' before options are loaded and then usually is an array of objects.
The cleanest way to fix this is add prop in your MUI <Select>:
- for controlled component:
value={options.length > 0 ? value : ''} - for uncontrolled:
value={options.length > 0 ? field.value : ''}wherefield.valuefor example comes fromreact-hook-formfrom<Controller render={({ field }) => ( ...wrapper around MUI<Select>
I got the same error and I solved it by making sure that the default value and the other select values thereafter are the same, for example if the default value is a string like '' then the other values are objects it will show the warning so to avoid such a problem make the default value to be either a [] or {} or most preferably null
To add to @Ait Friha Zaid response.
I also added the defaultValue attribute but also added an additional option:
const values = ['option 1', 'option 2', 'option 3']; <FormControl fullWidth> <InputLabel>{title}</InputLabel> <Select defaultValue="choose" label={title} onChange={e => func({...state, [keyName]: e.target.value}) } > <MenuItem disabled value="choose">Choose Option</MenuItem> {values.map((value) => ( <MenuItem value={value} key={value}>{value}</MenuItem> ))} </Select> </FormControl> That way you always have a disabled option that works as a placeholder which is the default option, and in case you want to do form validation, until the user changes the option, the state wont be changed.
I needed to use another approach since none of the solutions above worked for me.
I had to create the first element of the array I was going to use as the default to an actual value. In other words, I was making the first element '', but it needed instead to be ' '. Setting a default value of array[0] where array[0] = ' ' from the first item then worked.