0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【React】onClickの記述の仕方による関数の実行のタイミング

0
Last updated at Posted at 2025-05-31

概要

ReactもJavaScriptも初心者ですので、間違いなどあったらご指摘お願いいたします。
「TODOアプリ」を作成時、未完了のTODOリストに要素の「追加」ボタンと「完了」ボタン、「削除」ボタンを実装していた。
各ボタンに対してonClickを実装した際に、ボタンによって適切な記述の仕方が違ったので、まとめておきます。

onClickとは

onClickは、要素がクリックされたときに実行されるイベントハンドラーを定義するための特別な属性(イベントハンドラープロパティ)です。

<button onClick={onClickHandler}>ボタン1</button>

上記のコードでは、「ボタン1」を押下(click)すると、onClickHandler関数が渡されます。

要素の「追加」ボタン

要素の「追加」ボタンは以下のように、onClickAdd関数を渡すことで実現できます。

<button onClick={onClickAdd}>追加</button>

この時以下の点を理解できていなかったため、「完了」ボタンと「削除ボタン」の実装時に、予期せぬ挙動を生み出してしまいました。

  • onClickAdd ← これは「関数の名前(参照)」です
  • onClickAdd関数では、useStateを使ってset関数を利用している
  • onClick={onClickAdd} ← React に「この関数をクリック時に実行してね」と渡しているだけ

要素の「完了」ボタンと「削除」ボタン

これらも要素の「追加」ボタンと同様に記述すれば良いと考えたのが、間違いでした。
<間違った例> indexは完了する要素のキー

<button onClick={onClickComplete(index)}>完了</button>
  • 関数()という表記になっているため、onClickComplete関数即座に実行される
  • onClickComplete(index)関数では、useStateを使ってset関数を利用している
  • Reactがコンポーネントを再レンダリングする度に実行されるため、戻り値(多くの場合 undefined)を React に渡すことになる

→ その結果、ボタンを表示した瞬間に実行されてしまう。
しかも、それが再レンダリングのたびに起きると「複数回実行されたように見える」のです。
(試しにonClickComplete関数の中身をalert()に変更すると、ページが表示された瞬間に何回もウインドウが表示されます。)

解決法

「完了」ボタンと「削除」ボタンは、引数indexを取る必要があるため、関数(index)の形式を取らざるを得ない。
そのため、解決法としては、アロー関数を使って関数の宣言をすることで、クリックされた時(後で実行する)関数を渡すことができる。
<正しい例>

<button onClick={() => onClickComplete(index)}>完了</button>

「削除」ボタンもこれと同様に対処します。

まとめ

書き方 実行タイミング よくある要素
onClick={onClickAdd} クリックされたとき 引数なしの関数
onClick={onClickComplete(index)} 即座に実行される(ダメ!) バグの元
onClick={() => onClickComplete(index)} クリックされたとき 引数ありの関数を渡す時
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?