问题
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