😺

イベントハンドラで関数を渡す時の話(React)

2023/02/26に公開

実装方法

イベントハンドラの引数の有無によって分かれる
引数なし
onClick={関数オブジェクト}
onClick={() => 関数名()}

引数あり
onClick={() => 関数名(引数)}

イベントハンドラとは

一般的には、あるイベントが発生した時に、呼び出される処理のことを言います。

イベントの発火に対する応答としてコードのブロックが実行されるように定義する事を、イベントハンドラーを登録すると言います。

ここで重要なのはイベントハンドラには関数オブジェクト自身を渡すということです。

https://developer.mozilla.org/ja/docs/Learn/JavaScript/Building_blocks/Events

ダメな例

onClick={関数名()}を渡してもいいような気もしますが、予期しない動作になる可能性があります。
上記のような書き方では、画面描画時にイベントハンドラに関数を実行した結果を渡すことになってしまいます。

本来であれば、押したときに関数を実行してほしいのに、ページが表示された瞬間に関数が実行されるので、関数実行のタイミングがおかしいことになります。

function MyButton() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    // ダメな例 <button onClick={handleClick()}>
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  );
}

ここで、上のようなダメな例で書いてしまうと、
コンポーネント描画時にhandleClick関数を実行→setState関数の実行
する結果を渡してしまうことになるので、無限ループに陥ることはよくあります。

なぜアロー関数は大丈夫なのか?

onClick={() => 関数名()}onClick={関数名()}と似たような感じだし、何でアロー関数の方は大丈夫なの? と思うかもしれないのです。
アロー関数を従来の関数に戻してみると

// アロー関数
() => 関数名();// 従来の関数
function () {
 return 関数名();
}

関数を返却していることがわかります。
そのため、アロー関数を実行して関数自身を返却しているため、意図した動作になり問題ないです。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions

まとめ

イベントハンドラには関数のそれ自身を渡してあげるという意識を持ちましょう

関数を呼び出す 実行する ←→ 関数自身を渡す 
上記の棲み分けは意識しましょう

Discussion