質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

885閲覧

Reactのドキュメントを読んでいてonClick内の引数でわからない箇所

igarashi-haruki

総合スコア7

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2018/04/10 15:02

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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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のことは脇に一旦置いて、上記のコードをベースに説明します。

foo1barでは、fnという関数を渡しています。
foo2barでは、関数fnの実行結果を渡しています。

そのため、foo1.barfoo2.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()eundefinedとなり、エラーが起きてしまいます。

なので、onClick={handleClick}とするか、onClick={(e) => handleClick(e)}のようにしてあげる必要があります。この辺の詳細に関しては、つい先日、テラテイルで似たような質問に回答しましたので、こちらを参考になさって下さい。https://teratail.com/questions/120714

投稿2018/04/10 18:29

編集2018/04/10 22:21
HayatoKamono

総合スコア2415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

igarashi-haruki

2018/04/11 00:49

とても分かりやすい回答ありがとうございます!! レンダーされた時点でhandleClickが実行されることを忘れていました.
HayatoKamono

2018/04/11 01:22

良かったです!次回からは質問時に以下の質問のヒントを一読の上、質問時のアドバイスを参考に質問なさって見て下さい。https://teratail.com/help/question-tips 今回のような質問の場合であれば、どこまでは理解してるかなどの情報が質問文にないと、回答する側もどこから説明すると良いのか分からないので。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問