こんにちわ!本日はMUI5のイベント周りで少し問題があったので、詳しくご紹介したいと思います。何かの参考になれば幸いです。
現在開発中のプロジェクトではReact+Typescriptでコーディングしていて、MUI5でモダンなUIを取り入れています。MUI5のおかげでパッと華やかなUIが簡単に実現できて助かっているのですが、ドロップダウン(Select)を実装した際に少し問題が発生しました。
イベント発火元の要素が掴めない
実現したかったUIは下記のようにテーブルの各行にドロップダウンが埋め込まれたシンプルなものです。同じ選択肢のドロップダウンが複数個存在するのでイベント管理を行う場合は誰が発火したのかを把握する必要があります。
テーブル部分のコードはだいたい次のような形になるかと思います。
data.map(({ name }) => (
<TableRow hover key={name}>
<TableCell>{name}</TableCell>
<TableCell>
<Select
onChange={(e, child) => {
const element = e.currentTarget; // nullになる
// 処理
}}
fullWidth
value={data.find((f) => f.name === name)?.bloodType}
>
<MenuItem value="A型">A型</MenuItem>
<MenuItem value="B型">B型</MenuItem>
<MenuItem value="O型">O型</MenuItem>
<MenuItem value="AB型">AB型</MenuItem>
</Select>
</TableCell>
</TableRow>))
ドロップダウンの選択が切り替えられた際にonChangeでイベント(型はSelectChangeEvent)をコントロールしていますがMUI5ではこのイベント発火元の要素が掴めないのです。。。複数のドロップダウンを扱う際にこれは大きな障壁です。
SelectChangeEventについて
MUIのSelectが返すSelectChangeEventですが、targetプロパティには選ばれた選択肢のkeyを含むオブジェクトが返ってきますが発火元の要素(HTMLElement)ではありません。Material-UI v4の頃はcurrentTargetで発火元が取得できたそうですがMUI5では不具合なのかcurrentTargetにはnullが入り、まったく役に立ちません。
MUIのSelect APIをチェックしてみると、onChgageの第二引数でchild:ReactNodeが取得できると書いてあるのですがこれも発火元の情報を含まないようです。
解決策
色々調べてはみたものの有益な情報は得ることができませんでした。いつまでも悩むわけにはいかないので、onChangeによる管理をあきらめて送信ボタンが押された際にドロップダウンの値を地道に調べてまわることにしました。
Onchangeを管理しないとSelectコンポーネントのvalue属性の管理も捨てることになります。そのままではドロップダウンの値が変わりませんのでvalue属性を設定してはいけません。その場合でもdefaultValue属性を設定すれば初期値は設定可能です。
まとめ
今回はMUI5の不具合と思われる事象について触れました。最終的に場当たり的な解決策しか浮かばなかったのですがこういうこともありますよね(笑)。他に代案が見つかればまた追記したいと思います。
この記事が面白かった方、参考になった方は、是非「イイね」お願いします。