ES6 React: Will ES.Next's @autobind bind methods only once for each instance?

拜拜、爱过 提交于 2019-12-14 01:30:39

问题


There are a lot of questions/articles written on the numerous ways to handle binding in ES6 React, but most don't seem to address a problem outlined in the React docs (emphasis mine):

We recommend that you bind your event handlers in the constructor so they are only bound once for every instance:

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

For context, they're advising against in-line binding of methods, such as:

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

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

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

Sure. But the recommended solution of binding every method in the constructor is cumbersome w/ a lot of methods, so I was looking at the ES.Next @autobind decorator at class level as a simple solution:

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

What I can't figure out is: will this decorator have the same disadvantage of in-line binding methods? i.e., will the methods be bound just once for every instance?

If not, is there a succinct solution that avoids this pitfall?


回答1:


Class instance fields and their associated initializers solve the issue of having to assign properties with the same name as methods inside the constructor but with a more succinct syntax. The following example is possible with Babel's class properties transform:

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

This creates a new, bound tick property for each Counter instance. This creates the same number of bound functions as React.createClass did.

Without the instance field and initializer, the effect is the same (a bound tick property is created for each Counter instance) but with more verbose syntax:

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



回答2:


I wrote a small component that does binding all methods of other components. you can try it if you want: http://www.marouen-mhiri.com/react/autobinding-es6-classes-in-react-another-approach/



来源:https://stackoverflow.com/questions/37645914/es6-react-will-es-nexts-autobind-bind-methods-only-once-for-each-instance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!