Reputation: 751
In new React ES6 classes this
needs to be binded as stated here: http://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding
for eg:
class Counter extends React.Component {
constructor() {
super();
this.tick = this.tick.bind(this);
}
tick() {
...
}
...
}
The explanation for this is because it's the default behaviour, however if I make an ES6 class and then I make a new instance of it this
will be binded
import React from 'React'
class Test extends React.Component {
constructor() {
super()
}
foo () {
console.log('bar')
}
hello() {
this.foo()
}
}
var test = new Test()
test.hello()
// > bar
Why binding is needed in React then?
Upvotes: 8
Views: 1502
Reputation: 1827
Classes in ES6 are functions. When you instantiate a class, you get an object. For all the methods in your class, if you used this
inside them, it refers to the object that owns the method.
But it is confusing when you extract the method because the context changes. Examples:
let foo = Counter()
foo.tick()
If you call foo.tick()
, this
belongs to the object foo. Cool.
But watch this:
tickFunc = foo.tick()
tickFunc()
You detached the function from the original object, now the function invocation happens where this
inside tickFunc()
refers to the global object.
So why do you need to bind your methods in React? You do it because most of the times we are passing the method references either to the event handlers or as props to components. When you pass references of your methods, they become detached functions and their context changes. To solve that, you use bind()
in the constructor.
Upvotes: 3
Reputation: 77482
You need set this
to methods in case, for example, if you need pass function reference to event handlers, however you don't need set this
for every method.,
class Counter extends React.Component {
constructor() {
super();
this.tick = this.tick.bind(this);
}
tick() {
// this refers to Counter
}
fn() {
// this refers to Counter
}
withoutBind() {
// this will be undefined or window it depends if you use "strict mode" or not
}
render() {
this.fn(); // this inside this method refers to Counter
// but if you will do like this
const fn = this.fn;
fn(); // this will refer to global scope
return <div>
<button onClick={this.tick}>1</button>
<button onClick={this.withoutBind}>2</button>
</div>;
}
}
Upvotes: 5