526 文字
3 分

Reactのイベント型について

前提知識#

  • React におけるイベントはブラウザのネイティブイベントではなく、クロスブラウザ対応などを行ったラッパである。
  • これを合成イベント(Synthetic Event)と呼ぶ。
  • ネイティブイベントには、event.nativeEvent からアクセスできる。

React.XXXEventHandler#

button 要素の onClick の型定義。

const handleClick: React.MouseEventHandler<HTMLButtonElement> = (event) => {};
<button onClick={handleClick}>Some Component</button>;

これは次と同じ。

const handleClick = (event: React.MouseEvent<HTMLButtonElement>): void => {};
<button onClick={handleClick}>Some Component</button>;

React.FC と同様の理由で、React.XXXEventHandler 系を使うのは推奨しない。

React.XXXEvent#

Event 用の型のいくつかは 2 つ目のジェネリクスを持つが、適切な初期値が与えられているため基本的に指定する必要はない。

React.MouseEvent<HTMLElement, NativeEvent>;
React.DragEvent<HTMLElement>;
  • HTMLElement の型は、event.currentTarget で使われる。
    • currentTarget を使わないなら不要
  • NativeEvent の型は、event.nativeEvent で使われる。
    • nativeEvent をカスタマイズして利用しないのであれば不要
const handleClick = (event: React.MouseEvent) => {
window.alert("Hello, World");
};
<button onClick={handleClick}>Some Component</button>;

React.SyntheticEvent#

React のイベントは合成イベントであり、型においても SyntheticEvent を継承している。

何のイベントによって呼び出されたのかを気にしない OR したくないのであれば有益。

const handler = (event: React.SyntheticEvent<HTMLInputElement>) => {
console.log(event.type, event.currentTarget.value);
};
export const SomeComponent = () => {
return (
<input onChange={handler} onFocus={handler} onKeyDown={handler}>
Some Component
</input>
);
};

Event は必ず React から import すること#

React.MouseEvent と MouseEvent が存在する。

React から提供されない Event は、NativeEvent であるため正しく型が付かない。

まとめ#

React.MouseEventHandler<HTMLButtonElement>などハンドラー系の型は取り回しが悪いのでおすすめはしない。

MouseEventReact.MouseEventは別物であり、MouseEvent は NativeEvent であるため正しく型が付かない。React から提供されている Event を利用すること。

React から import されていない Native の Event 型は利用しない。React から提供されている React.MouseEvent や React.ChangeEvent などを利用する。

React.XXXEventHandler も取り回しが悪いためおすすめはしない。

また、event.currentTarget を利用しないのであれば、基本的にジェネリクスは指定しなくても問題はない。

イベントの種類を問わないなら、React.SyntheticEvent が使える。

Reactのイベント型について
https://blog.ohirunewani.com/posts/react-event-types/
作者
hrdtbs
公開日
2022-11-03
ライセンス
CC BY-NC-SA 4.0