背景
こちらを受講中に「あれ?」となったので、記事にして残しておく。
問題
buttonタグにonClickイベントハンドラーで関数を指定したときに、下記に記述したパターンだと、関数がレンダリングされたタイミングで即時実行されてしまった。
export const Todo = () => {
const onClickAlert = (text) => {
alert(text);
};
return (
<>
<button onClick={onClickAlert(text)}>アラートや</button>
</>
);
};
解決策
export const Todo = () => {
const onClickAlert = (text) => {
alert(text);
};
return (
<>
<button onClick={() => {onClickAlert(text)}}>アラートや</button>
</>
);
};
buttonタグ内で関数を定義してやると、ボタンを押したタイミングのみで実行されるようになった。
原因
JSXの{}の中はJavaScriptの式として評価されるからです
// これは評価すると値が出る式として扱われる
<button onClick={onClickAlert(text)}>アラートや</button>
JSだとこういうことを言っている感じ
const greet = () => {
return 'Hello!';
}
// 即時実行パターン
const result = greet();
console.log(result); // 'Hello!'
// ()を外して関数の参照のみ
const result = greet; // ここで'Hello'は実行されない
console.log(typeof result) // 'function'
-
greet()= 関数の実行、その戻り値 -
greet= 関数オブジェクトへの参照
まぁそりゃそうかという感じですね
なので、Reactのコードが引数を受け取らない、みたいなパターンであればこういう書き方はOK
export const Todo = () => {
const onClickAlert = () => {
alert('アラートです');
};
return (
<>
<button onClick={onClickAlert}>アラートや</button>
</>
);
};
こうしてあげると、クリック時にreactがonClickAlertを実行してくれます。
// onClickAlertは式ではなく値
<button onClick={onClickAlert}>アラートや</button>
感想
- 結構基本的な内容でしたが、フリーズしてしまいました。
- Reactというかプログラミング基礎の知識が抜けていたような…
参考