3

ES6 React でバインディングを処理するさまざまな方法について書かれた多くの質問/記事がありますが、ほとんどはReact docs (強調鉱山)で概説されている問題に対処していないようです:

コンストラクターでイベント ハンドラーをバインドして 、インスタンスごとに 1 回だけバインドすることをお勧めします。

constructor(props) {
  super(props);
  this.state = {count: props.initialCount};
  this.tick = this.tick.bind(this);
}

文脈上、彼らは次のようなメソッドのインラインバインディングに反対するようアドバイスしています:

//using .bind()
<div onClick={this.tick.bind(this)}>

// ES6 anon arrow functions
<div onClick={() => this.tick()}>

// ES.Next :: operator
<div onClick={::this.tick}>

もちろん。しかし、コンストラクター内のすべてのメソッドをバインドするという推奨される解決策は、多くのメソッドで面倒なので 、単純な解決策としてクラス レベルでES.Next @autobind デコレーターを検討していました。

import { autobind } from 'core-decorators';

@autobind
class Person {
  getPerson() {
    return this;
  }

  getPersonAgain() {
    return this;
  }
}

let person = new Person();
let { getPerson, getPersonAgain } = person;

getPerson() === person;
// true

getPersonAgain() === person;
// true

私が理解できないのは、このデコレーターにはインラインバインディングメソッドと同じ欠点がありますか? つまり、メソッドはインスタンスごとに 1 回だけバインドされますか?

そうでない場合、この落とし穴を回避する簡潔な解決策はありますか?

4

2 に答える 2

1

クラス インスタンス フィールドとそれに関連付けられた初期化子は、コンストラクター内のメソッドと同じ名前のプロパティをより簡潔な構文で割り当てなければならないという問題を解決します。次の例は、Babel のクラス プロパティ transformで可能です。

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: props.initialCount};
  }
  tick = () => {
    this.setState({count: this.state.count + 1});
  };
  ...
 }

tickこれにより、インスタンスごとに新しいバインドされたプロパティが作成されCounterます。これにより、作成したのと同じ数のバインドされた関数が作成されReact.createClassます。

インスタンス フィールドと初期化子がなくても、効果は同じですが (インスタンスtickごとにバインドされたプロパティが作成されCounterます)、より冗長な構文になります。

constructor(props) {
  super(props);
  this.state = {count: props.initialCount};
  this.tick = this.tick.bind(this);
}
tick() {
  this.setState({count: this.state.count + 1});
}
于 2016-09-27T19:18:07.457 に答える
0

他のコンポーネントのすべてのメソッドをバインドする小さなコンポーネントを作成しました。必要に応じて試すことができます: http://www.marouen-mhiri.com/react/autobinding-es6-classes-in-react-another-approach/

于 2016-06-10T18:47:23.760 に答える