Reputation: 2316
I'm trying to add an onChange event handler to the Select component from material-ui:
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={values.country}
onChange={handleCountryChange}
>
{countries.map(c => {
return (
<MenuItem value={c}>{c}</MenuItem>
)
})}
</Select>
and my event handler:
const handleCountryChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
setValues({...values, country: event.target.value});
};
but I get the following error:
Type '(event: ChangeEvent) => void' is not assignable to type '(event: ChangeEvent<{ name?: string | undefined; value: unknown; }>, child: ReactNode) => void'.
What's wrong?
Upvotes: 43
Views: 64377
Reputation: 9
I also encountered such an issue in my app. Here is how I solved it (I provide you the whole example):
import { useState } from 'react'
import SelectState from './components/SelectState';
import { SelectChangeEvent } from '@mui/material';
const App = () => {
const [state, setState] = useState('');
const handleStateChange = (event: SelectChangeEvent) => {
setState(event.target.value as string);
}
return (
<div className='bg-[#AB92BF] w-[100wh] h-[100vh] p-4'>
<SelectState state={state} onSelectChange={(event: SelectChangeEvent) => handleStateChange(event)} />
</div>
)
}
export default App;
import { Box, FormControl, InputLabel, MenuItem, Select } from '@mui/material'
import { SelectStateProps } from '../interface'
const SelectState = ({ state, onSelectChange }: SelectStateProps) => {
return (
<Box sx={{ minWidth: 220 }}>
<FormControl fullWidth>
<InputLabel id="state-select-label">State</InputLabel>
<Select
labelId="state-select-label"
id="state-select"
value={state}
label="Age"
onChange={onSelectChange}
>
<MenuItem value={"America/Los_Angeles"}>Los Angeles</MenuItem>
<MenuItem value={"America/New_York"}>New York</MenuItem>
<MenuItem value={"America/Detroit"}>Detroit</MenuItem>
</Select>
</FormControl>
</Box>
)
}
export default SelectState
import { SelectChangeEvent } from "@mui/material";
export interface SelectStateProps {
state: string;
onSelectChange: (event: SelectChangeEvent) => void;
}
Upvotes: 0
Reputation: 21
im using import Select from '@mui/joy/Select'; import Option, { optionClasses } from '@mui/joy/Option';
all the solutions from the above didn't work
this did work
const handleChange = (event: React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent | React.FocusEvent<Element, Element> | null, value: any) => { setSort(value); };
Upvotes: 2
Reputation: 196
None of these are correct IMO. Casting "as" should generally be avoided since you'll lose the type checking you get from letting the code infer the type. It's also weird to explicitly type it as unknown
only to later cast it to a string. Ideally you'd use a typeguard if you truly didn't know. To be clear, if somehow event.target.value
is actually a boolean and we're casting it to a string here we won't know until the app throws a bug later down the line.
The docs (https://mui.com/material-ui/api/select/) have this as the onChange signature:
function(event: SelectChangeEvent<T>, child?: object) => void
event: The event source of the callback. You can pull out the new value by accessing event.target.value (any).
Warning: This is a generic event not a change event unless the change event is caused by browser autofill.
child: The react element that was selected when native is false (default).
So with that in mind it becomes:
const handleCountryChange = (event: SelectChangeEvent) => {
setValues({...values, country: event.target.value });
};
We don't need to define T here explicitly as a string because it's a string by default. HTML inputs read in as strings.
Upvotes: 12
Reputation: 67
Had that issue while using Material UI. Didn't know they had their own types
import { SelectChangeEvent } from '@mui/material/Select';
const changeSymbol = (event: SelectChangeEvent) => {
console.log(event)
}
Upvotes: 5
Reputation: 95
I don't know where it's documented, but the Select module also exports SelectChangeEvent. This is what I used to get it:
import Select, {SelectChangeEvent} from '@mui/material/Select';
const handleGenerationSelectChange = (event: SelectChangeEvent<string>, child: React.ReactNode) => {
let genHolder = currentGeneration;
genHolder.source = event.target.value as string;
setCurrentGeneration({...genHolder});
};
Upvotes: 0
Reputation: 433
Seemed counterintuitive for me either, but I had to do this:
const handleChange = (e: ChangeEvent<{ value: string | unknown }>) => formik.setFieldValue('field', e.target.value)
Upvotes: 1
Reputation: 2983
This is proper for the latest MUI 5 / Select
import { SelectChangeEvent } from "@mui/material";
const handleOnChange = (event: SelectChangeEvent<unknown>) => {
const value = event.target.value as YourEnumType;
};
Upvotes: 29
Reputation: 11770
Since MUI Select in not a real select element you will need to cast e.target.value
using as Type
and type the handler as React.ChangeEvent<{ value: unknown }>
const handleCountryChange = (event: React.ChangeEvent<{ value: unknown }>) => {
setValues({...values, country: event.target.value as string});
};
Upvotes: 66
Reputation: 1712
It seems the definition for the change event is incorrect in the SelectInput.d.ts
. More here: https://github.com/mui-org/material-ui/issues/15400#issuecomment-484891583
Try to use their recommended signature:
const handleCountryChange = (event: any) => { ... }
Upvotes: -6