Reactのドキュメントを読んでいて一部わからない所があったのでわかる人いたら教えてください。
onClickの引数は何故onClick={handleClick()}ではないのでしょうか?
教えていただけるとありがたいです。
該当のソースコード
function ActionLink() { function handleClick(e) { e.preventDefault(); console.log('The link was clicked.'); } return ( <a href="#" onClick={handleClick}> Click me </a> ); }
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
onClickの引数は何故onClick={handleClick()}ではないのでしょうか?
リンク先のサンプルコードの場合においては、handleClick()
とするとエラーが発生してしまいます。その理由は最後で説明しますが、場合によっては、onClick={handleClick()}
であってもエラーにはなりません。ただし、通常、onClickに渡す値であれば、handleClick
のようにすることになります。理由は後述します。
まずは普通のJavaScriptで確認してみる
function fn() { return 1; } const foo1 = { bar: fn }; const foo2 = { bar: fn() }; console.log(foo1.bar); // [Function: fn1] console.log(foo2.bar); // 1
まず、onClickのことは脇に一旦置いて、上記のコードをベースに説明します。
foo1
のbar
では、fn
という関数を渡しています。
foo2
のbar
では、関数fn
の実行結果を渡しています。
そのため、foo1.bar
、foo2.bar
のログを出力すると、一方は [Function: fn1]
となり、もう一方は1
となります。
なので、onClick={handleClick}
とonClick={handleClick()}
では、そもそも、onClick
に渡している値が違うことをここで確認して下さい。
これをふまえて、reactをベースに説明を続けます。
次にReactベースで確認してみる
function ActionButton() { function handleClick() { console.log('The button was clicked.'); } return ( <button onClick={handleClick()}>aaa</button> ); }
このコードは質問文のコードをベースにしていますが、少し変更を加えています。
違いはa
タグをbutton
タグに変えたことと、handleClick
メソッドの中でのe.preventDefault()
の呼び出しを削除したくらいです。
さて、先ほどのJavaScriptをベースにした説明を思い出していただくとわかると思いますが、onClick={handleClick()}
とした場合、handleClick
関数を実行し、その結果をonClick
に渡していることになります。その為、このコードの場合、ボタンがレンダーされた時点でhandleClick
関数が実行されてしまいます。また、このコードの場合、ボタンをクリックしてもonClick
に渡された値は、handleClick
関数が返すundefined
である為、何もおきません。(handleClick
関数はただログを出力するだけの関数なので戻り値はなく、undefined
が返るだけです。)
function ActionButton() { function handleClick() { console.log('The button was clicked.'); } return ( <button onClick={handleClick}>aaa</button> ); }
一方、onClick={handleClick}
とした場合は、onClick
にはhandleClick
関数そのものを渡しているので、ボタンをクリックする度に、handleClick
関数が実行されることになります。
最後に質問文のコードで確認してみる
function ActionLink() { function handleClick(e) { e.preventDefault(); console.log('The link was clicked.'); } return ( <a href="#" onClick={handleClick()}> Click me </a> ); }
ここまでの説明でもう十分かとは思いますが、一応、最後に質問文にあったコードを例に説明をします。
今までに示したコードの場合はどちらのパターンでもエラーは起きないのですが、質問にあったコードをベースにした上で、かつ、<a href="#" onClick={handleClick()}>
とした場合は、エラーが起きてしまいます。
質問文のコードの場合、handleClick
関数の引数にSyntheticEvent
オブジェクトが渡ってくることが期待されており、それを前提に関数内でe.preventDefault()
が実行されています。
ですが、すでに説明した通り、onClick={handleClick()
とした場合、まず、コンポーネントがレンダーされる時点で、handleClick
関数が実行されます。その際、引数には何も渡されていないため、handleClick
関数内で呼ばれるe.preventDefault()
のe
がundefined
となり、エラーが起きてしまいます。
なので、onClick={handleClick}
とするか、onClick={(e) => handleClick(e)}
のようにしてあげる必要があります。この辺の詳細に関しては、つい先日、テラテイルで似たような質問に回答しましたので、こちらを参考になさって下さい。https://teratail.com/questions/120714
投稿2018/04/10 18:29
編集2018/04/10 22:21総合スコア2415
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/04/11 00:49
2018/04/11 01:22