O hirunewani blog

Reactのイベント型について

Created at

Reactのイベント型について書いた。React.MouseEvent、React.ChangeEvent、React.SyntheticEvent、NativeのEvent型、React.XXXEventHandlerなどについて、どれを使うべきか。

前提知識

  • 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が使える。