blog.takurinton.dev

Preact の change event

2021-09-19

こんにちは

どうも、僕です。

先日、Preact を使用して、簡単なアプリケーションのプロトコーディングをしていて、input タグのイベントハンドラを呼ぼうとしたらうまく動かくてハマりました。

以下のように定義していたのですが、結論としては、`onChange` ではなくて `onInput` を使わなければならないようです。

const HogeComponent = (): JSX.Element => {
  const onChange = ({ currentTarget }: JSX.TargetedEvent) => {
    setValue(currentTarget.value);
  };

  // これでは動かない
  return ;

  // これで動く
  return ;
}

その差分を埋めるための [preact/compat](https://github.com/preactjs/preact-compat) というツールも用意されていますが、今回はそれを使っていなかったのでハマってしまいました。

どうしてこうなったのか

Preact のドキュメントの [Differences to React](https://preactjs.com/guide/v10/differences-to-react/) というページに記述がありました。

In Preact core, onChange is the standard DOM change event that gets fired when an element's value is committed by the user.

React onChange イベントは独自実装ではあるものの、実際にはブラウザで実行される [GlobalEventHandlers.onInput](https://developer.mozilla.org/ja/docs/Web/API/GlobalEventHandlers/oninput) と同じであり、Preact はその部分を直接使用して要素にアタッチをします。そのため、構文に差が生まれているということです。

これについてツイートをしたら、リプが飛んできました。DevRel ありがたい...。

https://twitter.com/takurinton/status/1438688299388862467?s=20

Preact では compat を使ってない限り change event は onChange ではなくて onInput を使うらしい
40分くらいハマってた...。https://t.co/cYfWiyQKB4

— ポラロイドが欲しい (@takurinton) September 17, 2021

Preact では軽量化のためもあり、ユーザーが指定したイベントやセレクタを愚直に実DOMに反映していきますが、React では内部でごにゃごにゃやってくれています。自分もまだしっかりコードが読めているわけではないので、そこまでしっかり把握しているわけではないのですが、どうやら意外と Preact と React には差があることがわかりました。

まとめ

ライブラリを使う前には、ドキュメントをしっかり読んだり、特に今回みたいに似てるライブラリを使う時にはそのライブラリとの差はなんなのかについてしっかり確認し、特性を掴んだ上で使用するようにしましょう。

Preact は主に、ネイティブのブラウザのイベントをそのまま実行していますが、React はどうやら中でいろいろ動作が行われていること、React の JSX 記法で書きたかったら、preact/compat を噛ませないといけないことなどがわかりました。

Preact は非常に軽量で、Jason Miller 氏による過剰なまでの最適化が行われているため、非常に面白い技術です。自分もこれから小さいものや、プロトコーディングをするときなどは積極的に使用していきたいなと思いました。

おしまい