web-dev-qa-db-ja.com

Reactで関数とイベントハンドラーをバインドする必要があるのはなぜですか?

class SomeClass extends Component{
  someEventHandler(event){
  }
  render(){
    return <input onChange={------here------}>
  }
}

------here------パーツのバージョンが異なります。

// 1
return <input onChange={this.someEventHandler.bind(this)}>

// 2
return <input onChange={(event) => { this.someEventHandler(event) }>

// 3
return <input onChange={this.someEventHandler}>

バージョンはどう違うのですか?それとも好みの問題ですか?


回答とコメントをありがとうございました。すべてが役に立ちます。これについて私と混同されている場合は、このリンク[〜#〜]最初[〜#〜]を読むことを強くお勧めします。
http://blog.andrewray.me/react-es6-autobinding-and-createclass/

19
kukrt

バインディングはReactに固有のものではなく、Javascriptでthisがどのように機能するかです。すべての関数/ブロックには独自のコンテキストがあり、関数の呼び出し方法に固有のものです。 Reactチームは、ES6を追加するときに、クラスのカスタムメソッド(別名thisのような組み込みメソッドではない)にバインドされないようにcomponentDidMountを決定しました。サポート(クラス構文)。

コンテキストをバインドする必要があるのは関数の目的によって異なります。クラスの小道具、状態、またはその他のメンバーにアクセスする必要がある場合は、バインドする必要があります。

あなたの例では、それぞれが異なり、コンポーネントの設定方法によって異なります。

クラスへの事前バインド

.bind(this)は、thisコンテキストをコンポーネント関数にバインドするために使用されます。ただし、レンダリングサイクルごとに新しい関数参照が返されます。 (クリックハンドラーのように)関数の使用ごとにバインドしたくない場合は、関数を事前にバインドできます。

a。コンストラクターでバインディングを行います。別名

_class SomeClass extends Component{
    constructor(){
        super();
        this.someEventHandler = this.someEventHandler.bind(this);
    }
    someEventHandler(event){
    }
    ....
} 
_

b。クラスfatarrow関数でカスタム関数を作成します。別名

_class SomeClass extends Component{
    someEventHandler = (event) => {
    }
    ....
}
_

クラスへの実行時バインディング

これを行うためのいくつかの一般的な方法

a。コンポーネントハンドラー関数をインラインラムダ(太い矢印)関数でラップできます。

_onChange={(event) => { this.someEventHandler(event) }
_

これにより、クリックハンドラー<input onChange={(event) => { this.someEventHandler(event, 'username') }>に追加のデータを渡す必要がある場合などの追加機能を提供できます。 bindでも同じことができます

b。上記のように.bind(this)を使用できます。

_onChange={this.someEventHandler.bind(this) }
_

追加のパラメータ<input onChange={this.someEventHandler.bind(this, 'username') }>

新しい関数参照の作成を避けたいが、それでもパラメーターを渡す必要がある場合は、それを子コンポーネントに抽象化するのが最善です。 詳細はこちら

あなたの例では

_// 1
return <input onChange={this.someEventHandler.bind(this)}>
_

これは、ランタイムイベントハンドラーをクラスにバインドするだけです。

_// 2
return <input onChange={(event) => { this.someEventHandler(event) }>
_

クラスにバインドする別のランタイム。

_// 3
return <input onChange={this.someEventHandler}>
_

追加のパラメーターなしで、クリックイベントが発生したときにトリガーするコールバック関数として関数を渡すだけです。必ず事前にバインドしてください。

要約する。コードを最適化する方法について考えるのは良いことです。それぞれの方法には、必要に応じてユーティリティ/目的があります。

13
John Ruddell

なぜa React関数をバインドするのですか?

ES6クラスを使用してコンポーネントを定義する場合、一般的なパターンは、イベントハンドラーがクラスのメソッドになることです。 JavaScriptでは、クラスメソッドはデフォルトではバインドされていません。 _bind this.someEventHandler_を忘れてonChangeに渡すと、関数が実際に呼び出されたときにこれは未定義になります。

一般に、_()_のように、後に_onChange={this.someEventHandler}_がないメソッドを参照する場合は、そのメソッドをバインドする必要があります。

onChange関数を正しいコンテキストにバインドする方法は3つあります

最初

_return <input onChange={this.someEventHandler.bind(this)}>
_

これでは、bindを明示的に使用して、onChangeイベントをeventHandlerの引数として使用できるように機能させます。次のような構文タイプで他のパラメータを送信することもできます

_return <input onChange={this.someEventHandler.bind(this, state.value)}>
_

2番目

_return <input onChange={(event) => { this.someEventHandler(event) }>
_

これはES6構文であり、someEventHandler関数に渡すパラメーターを指定できます。これは.bind(this)と同等ですが、次のようなイベントと共に他の属性を送信する柔軟性も提供します

_return <input onChange={(event, value) => { this.someEventHandler(event, value) }>
_

番目

Arrow関数を使用してsomeEventHandler関数を定義します。

_someEventHandler = () => {
    console.log(this); // now this refers to context of React component
}
_

_arrow function_には独自のthisがなく、囲んでいる実行コンテキストのthis値が使用されるため、上記の関数は正しいコンテキストを取得します。

またはコンストラクターでバインド like

_constructor(props) {
   super(props);
   this.someEventHandler = this.someEventHandler.bind(this);
}


return <input onChange={this.someEventHandler}>
_

このメソッドでは、イベントはsomeEventHandler関数に直接アタッチされます。この方法で他のパラメーターを渡すことはできません

15
Shubham Khatri