関数コンポーネントで、「ボタンがクリックされたときは関数を呼び出す」というようなイベントハンドラを設定する場合について。
イベントハンドラの引数の有無によって分かれる。
とりあえずアロー関数にしておけば良い
- 引数無し
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()
のように実行されているのだろうが、まだ追えていない
- おそらく