地味にハマったのでメモします
MUI v5のSelectコンポーネントを使用してデータのバインディングを行なっていた時のエラーについて。
結論
問題はSelectコンポーネントの、eventを受け取る方法がMUIv5だとv4と異なる事でした。
以下はエラーが起こった時のコードになるのですが、v4だと動きます。
-
v4のポイントは、selectのeventハンドラを受け取るときはあらかじめデータ型を定義できない仕様のようで、以下のようにunknownで定義しています。
handleSelectCatChange = (e: React.ChangeEvent<{ value: unknown }>)
-
そして受け取った後valueに
as number
として型を定義する流れです。
const SomeForm:React.FC () => {
//selectが変化するたびにeditCategoryが配列をstateに伝えています。
const handleSelectCatChange = (e: React.ChangeEvent<{ value: unknown }>) => {
const value = e.target.value as number;
dispatch(editCategory({ ...categorys, category: value }));
};
//カテゴリー一覧をmapで回す用の関数
let categoryList = category.map((cat) => (
<MenuItem key={cat.id} value={cat.id}>
{cat.item}
</MenuItem>
return (
<FormControl className={classes.field}>
<InputLabel>Category</InputLabel>
<Select
name="category"
value={editedTask.category}
onChange={handleSelectCatChange}
>
{categoryList}
</Select>
</FormControl>
)
}
v5ではどうなのか?
v5ではMUIv5があらかじめ専用のSelectChangeEvent
コンポーネントを用意してくれています。
① eventハンドラの型を,以下のように定義します。
const handleSelectRespChange = (e: SelectChangeEvent<number>)
② またeventハンドラのvalueにもnumberの型をつけることで、入力された値に対しても型定義するとエラーが出なくなりました。
import { SelectChangeEvent} from "@mui/material";
const SomeForm:React.FC () => {
const handleSelectRespChange = (e: SelectChangeEvent<number>) => {
const value: number = e.target.value as number;
dispatch(editTask({ ...categorys, category: value }));
};
//カテゴリー一覧をmapで回す用の関数
let categoryList = category.map((cat) => (
<MenuItem key={cat.id} value={cat.id}>
{cat.item}
</MenuItem>
return (
<FormControl className={classes.field}>
<InputLabel>Category</InputLabel>
<Select
name="category"
value={editedTask.category}
onChange={handleSelectCatChange}
>
{categoryList}
</Select>
</FormControl>
)
}
まとめ
公式にもこれといった情報がなかった?かもしれないので、記録に残しました。
参考になったのは、スタックオバーフローです。
まだ仕組みを完全に理解しているわけではないので、詳しいかたがいましたらコメントをください👍