一、はじめに#
react
アプリケーションでは、イベント名はすべて小文字のキャメルケースで書かれます。たとえば、onclick
はonClick
に変更する必要があります。
最も簡単なイベントバインディングは次のようになります:
class ShowAlert extends React.Component {
showAlert() {
console.log("Hi");
}
render() {
return <button onClick={this.showAlert}>show</button>;
}
}
上記のコードからわかるように、イベントバインディングのメソッドは{}
で囲む必要があります。
上記のコードは問題がないように見えますが、処理関数の出力コードをconsole.log(this)
に変更すると、ボタンをクリックするとコンソールにundefined
が出力されることがわかります。
二、バインディングの方法#
上記のthis
を正しく出力するために、一般的なバインディング方法は次のとおりです:
- render メソッド内での bind の使用
- render メソッド内でのアロー関数の使用
- constructor 内での bind
- 定義時にアロー関数を使用してバインドする
render メソッド内での bind の使用#
クラスコンポーネントを使用する場合、特定のコンポーネント / 要素にonClick
属性を設定すると、そのthis
が現在のコンポーネントに自動的にバインドされません。この問題を解決するためには、イベント関数の後に.bind(this)
を使用してthis
を現在のコンポーネントにバインドする必要があります。
class App extends React.Component {
handleClick() {
console.log('this > ', this);
}
render() {
return (
<div onClick={this.handleClick.bind(this)}>test</div>
)
}
}
この方法では、コンポーネントがrender
されるたびにbind
が実行されるため、パフォーマンスに影響があります。
render メソッド内でのアロー関数の使用#
ES6
のコンテキストを使用して、this
の参照先を現在のコンポーネントにバインドします。同様に、各render
時に新しいメソッドが生成されるため、パフォーマンスに影響します。
class App extends React.Component {
handleClick() {
console.log('this > ', this);
}
render() {
return (
<div onClick={e => this.handleClick(e)}>test</div>
)
}
}
constructor 内での bind#
constructor
で事前に現在のコンポーネントをbind
することで、render
操作での重複バインドを回避できます。
class App extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log('this > ', this);
}
render() {
return (
<div onClick={this.handleClick}>test</div>
)
}
}
定義時にアロー関数を使用してバインドする#
前述の方法 3 と同様に、render
操作での重複バインドを回避できます。実装も非常にシンプルです。
class App extends React.Component {
constructor(props) {
super(props);
}
handleClick = () => {
console.log('this > ', this);
}
render() {
return (
<div onClick={this.handleClick}>test</div>
)
}
}
三、違い#
上記の 4 つの方法の違いは次のとおりです:
- コーディングの面:方法 1 と方法 2 はシンプルな書き方ですが、方法 3 は冗長な書き方です。
- パフォーマンスの面:方法 1 と方法 2 は、コンポーネントが
render
されるたびに新しいメソッドインスタンスが生成されるため、パフォーマンスに問題があります。関数が子コンポーネントにプロパティ値として渡される場合、余分なレンダリングが発生します。一方、方法 3 と方法 4 は 1 つのメソッドインスタンスしか生成しません。
上記を総合すると、方法 4 が最適なイベントバインディング方法です。