web-dev-qa-db-ja.com

Reactイベントハンドラーにおけるthisの値

何らかの理由で、この値がreactイベントハンドラーで失われています。反応と思ったドキュメントを読んで、これが正しい値に設定されていることを確認するためにここでいくつかのことを行いました

以下は期待どおりに機能しません

import React from 'react';

export default class Observer extends React.Component {

    handleClick() {
        console.log(this); //logs undefined
    }
    render() {
        return (
            <button onClick={this.handleClick}>Click</button>
        );
    }
}

しかし、これは:

import React from 'react';

export default class Observer extends React.Component {

    handleClick() {
        console.log(this); //logs Observer class instance
    }
    render() {
        return (
            <button onClick={this.handleClick.bind(this)}>Click</button>
        );
    }
}

ReactとES6は初めてですが、これは正しい動作ではないようです。

21
jamie holliday

これはJavaScriptの正しい動作であり、新しいclass構文を使用する場合はReactです。

自動バインド機能はES6クラスには適用されません v0.13.0。

だからあなたは使う必要があります:

 <button onClick={this.handleClick.bind(this)}>Click</button>

または、他のトリックの1つ:

export default class Observer extends React.Component {
  constructor() {
    super();
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    /* ... */
  }
  render() {
      return <button onClick={this.handleClick}>Click</button>
  }
}
32
WiredPrairie

受け入れられた回答は適切であり、ES6でよく使用しましたが、ES7で使用する別の「よりモダンな」ソリューションを追加したいだけです( (Reactコンポーネントクラスの自動バインディングに関する注意事項)に記載 ):矢印関数を クラスプロパティ として使用すると、ハンドラをどこでもバインドまたはラップする必要がありません。

export default class Observer extends React.Component {
  handleClick = (e) => {
    /* ... */
  }
  render() {
      return <button onClick={this.handleClick}>Click</button>
  }
}

これは、最もシンプルでクリーンなソリューションです。

15
Aaron Beall

他の人が言ったように、Reactは、ES6クラスを使用する場合、インスタンスにメソッドを自動バインドしません。それは、onClick={e => this.handleClick()}

代わりに:onClick={this.handleClick.bind(this)}

これは、テストでhandleClickメソッドをスパイに置き換えることができることを意味するため、バインドを使用する場合はできません。

10
Anders Ekdahl