Skip to content

Instantly share code, notes, and snippets.

@Aminevsky
Created July 4, 2020 06:56
Show Gist options
  • Save Aminevsky/daa64a19de9803e2cd0dde0d2c08a901 to your computer and use it in GitHub Desktop.
Save Aminevsky/daa64a19de9803e2cd0dde0d2c08a901 to your computer and use it in GitHub Desktop.
Reactの関数コンポーネントでイベントハンドラを設定する場合について

関数コンポーネントで、「ボタンがクリックされたときは関数を呼び出す」というようなイベントハンドラを設定する場合について。

要約

イベントハンドラの引数の有無によって分かれる。

とりあえずアロー関数にしておけば良い

  • 引数無し
    • onClick={関数オブジェクト}
    • onClick={() => 関数名()}
  • 引数有り
    • onClick={() => 関数名(引数)}

引数無し

関数オブジェクト

<button onClick={showDetail}>編集</button>

この場合、以下のような JavaScript が生成される。

onClick に関数オブジェクトが渡されていることに注目。

function showDetail() {
  console.log("called");
}

function TodoListItem(props) {
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", {
    onClick: showDetail
  }, "\u7DE8\u96C6")));
}

アロー関数

<button onClick={() => showDetail()}>編集</button>

この場合、以下のような JavaScript が生成される。

アロー関数が function を使った関数宣言に変換されて、 onClick に渡されていることに注目。

function showDetail() {
  console.log("called");
}

function TodoListItem(props) {
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", {
    onClick: function onClick() {
      return showDetail();
    }
  }, "\u7DE8\u96C6")));
}

引数有り

関数オブジェクト(動かない)

<button onClick={showDetail(1)}>編集</button>

イベントハンドラに引数を渡す場合に、このように書くと、以下のような期待しない動作をする。

  • ページを読み込んだだけで、イベントハンドラが起動してしまう
  • ボタンをクリックしても、イベントハンドラが起動しない
    • 開発者ツールで確認すると、 <button> にイベントが設定できていない

この場合に生成される JavaScript は以下のとおり。

onClick に渡されている値が showDetail(1) になっていることに注目。

function showDetail(todoId) {
  console.log(todoId);
}

function TodoListItem(props) {
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", {
    onClick: showDetail(1)
  }, "\u7DE8\u96C6")));
}

アロー関数

引数がある場合は、アロー関数を使わなければならない。

<button onClick={() => showDetail(1)}>編集</button>

この場合、以下のような JavaScript が生成される。

onClick の設定値が、引数無しの場合とほぼ同じになっていることに注目。

function showDetail(todoId) {
  console.log(todoId);
}

function TodoListItem(props) {
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", {
    onClick: function onClick() {
      return showDetail(1);
    }
  }, "\u7DE8\u96C6")));
}

備考

参考

まだよく分かっていないこと

  • なぜ読み込んだだけでイベントハンドラが実行されるのか
    • onClick={showDetail(1)} と書いたときは、中括弧の中が愚直に実行されているということ?
  • onClick はどのように実行されるのか
    • おそらく TodoListItem().onClick() のように実行されているのだろうが、まだ追えていない
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment