teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

{}つける

2017/11/24 11:58

投稿

raccy
raccy

スコア21784

answer CHANGED
@@ -27,14 +27,14 @@
27
27
 
28
28
  もちろん、これは**正常に動きません**。なぜなら、onClickには`handleClick`という**関数だけ**を渡しているため、`this`が何であるかという情報が欠如されるからです。クリックによってコールバックで呼び出されるときに`this`はこのオブジェクトのことではなくなり、`this.setState()`の呼出しに失敗します。
29
29
 
30
- それを解決する手段の一つとして、`{(e) => this.handleClick(e)}`があったのです。こちらは`=>`によって`this`が束縛されるため、`this`がこのオブジェクトであるところの関数というものをonClickに渡します。ですので、コールバックでも`this`が何か別のものになるのを防ぎます。他の解決方法として`this.handleClick.bind(this)`とする方法や、コンストラクタで`this.handleClick = this.handleClick.bind(this);`としておくという方法があります。そして、第4の方法として、該当コードであるClass Fieldsを用いた記法が(まだ正式では無いが)できるようになったと言うことです。
30
+ それを解決する手段の一つとして、`{(e) => this.handleClick(e)}`があったのです。こちらは`=>`によって`this`が束縛されるため、`this`がこのオブジェクトであるところの関数というものをonClickに渡します。ですので、コールバックでも`this`が何か別のものになるのを防ぎます。他の解決方法として`{this.handleClick.bind(this)}`とする方法や、コンストラクタで`this.handleClick = this.handleClick.bind(this);`としておくという方法があります。そして、第4の方法として、該当コードであるClass Fieldsを用いた記法が(まだ正式では無いが)できるようになったと言うことです。
31
31
 
32
32
  つまり、イベントのコールバックされる関数の`this`の問題に対する解決方法について、次のいずれかを行えば良いとなります。
33
33
 
34
- 1. アロー関数`=>`で囲って渡す。
34
+ 1. アロー関数`=>`で囲って渡す。`{(e) => this.handleClick(e)}`
35
- 2. `bind(this)`して渡す。
35
+ 2. `bind(this)`して渡す。`{this.handleClick.bind(this)}`
36
- 3. コンストラクタで`bind(this)`しておく。
36
+ 3. コンストラクタで`bind(this)`しておく。`this.handleClick = this.handleClick.bind(this);`
37
- 4. Class Fieldsでアロー関数を使う。
37
+ 4. Class Fieldsでアロー関数を使う。`handleClick = (e) => {...};`
38
38
 
39
39
  これはどれか一つだけで十分であり、複数を採用することは意味がありません。どれがいいかは一長一短になります。1.は毎回アロー関数を作るコストがかかります。2.も毎回新しい関数オブジェクトを作っています。3.はメソッド定義とコンストラクタにそのメソッドに対する情報が分散しています。4.はまだstage 3であり、仕様が変わる恐れがあります。
40
40