Binding functions in React

One of the reasons to use React for development, and I think one of the reasons for its popularity is that it relies heavily on all of the Javascript you already know. On a basic level it is taking a component’s state, a Javascript object, and using Javascript functions to manipulate that state. The page is then rendered to reflect those changes.
The fact that it relies so heavily on plain Javascript can be good and bad depending on how strong your Javascript skills are. The ideas of classes, event handling, importing, exporting, callback functions, etc. are all used in React and if you aren’t comfortable with them, then your time with React may be rough until you shore up those skills.
One Javascript concept in particular is used quite a bit in React applications and it is one that continues to trip up most everyone the first (or second, or third…) time they encounter it.
I’m taking about the dreaded keyword ‘this’.
Who knew that four little letters could strike so much fear into so many?
React doesn’t treat ‘this’ any differently than Javascript. It’s just that you may encounter it more in React since it uses classes and constructors to create components. Those components have methods attached to them. Components contain their own state and pass down properties to child components. All of these things are referred to using ‘this’ so if you write a React application, you will be using ‘this’ a lot.
Why ‘this’?
Since ‘this’ is used in React the same way it is used in Javascript, it may be helpful to explain why ‘this is used at all. It comes down to context. When you invoke a function, ‘this’ determines which object is the focus of the function. Here is an example with a function in the global scope:
var example = function() {
console.log(this);
}
No big deal, right? This is just creating a variable whose value is a function and logs out the value of ‘this’. What happens when you run it? When you are in the global scope you get the following:

When you invoke the example()
function, it returns the value of ‘this’ within the context, which in this case is the ‘Window’ object. The global object that all Javascript functions run in unless otherwise specified.
Let’s take this one step further. What if we use that same function, but we change it’s context. Look at the following:
var example = function() {
console.log(this);
}var exampleObj = {
insideObj: example
}
Here I have the original example()
function but this time instead of invoking it in the global scope, I’ve made it the value inside of an object. In Javascript, objects define their own scope, so what happens when I invoke this function?

What is logged to the console is now an ‘Object’, not the ‘Window’ like it was before. The context for ‘this’ has changed because it was invoked from somewhere else.
This context switching can be hard to keep track of but is very important and will break your React application if you don’t remember to set it correctly.
A React example
Here is a simple React example to drive this point home. Here I have an App component that renders a button that when clicked calls a handleClick()
method that will eventually change the state of App to track the number of times the button has been clicked.
import React, { Component } from 'react';class App extends Component {
constructor(props) {
super(props);this.state = {
numOfClicks: 0
};
}handleClick() {
console.log('From handleClick()', this);
}render() {
console.log('From render()', this);
return (
<div>
<button onClick={this.handleClick}>Click Me!</button>
<p>Number of Times Clicked = {this.state.numOfClicks}</p>
</div>
)
}
}export default App;
For this example, I’ve placed some console.log()
statements here so that you can see the problem. When the page is rendered and the button is clicked, this is what is logged to the console.

From inside render()
‘this’ is set to the App (really what will be an instance of this App component), but at this point, ‘this’ in the function is null
. The problem here is I need handleClick()
to update the state of this component and this is done with this.setState()
. The ‘this’ in this.setState()
will also be set to null
.
handleClick() {
console.log('From handleClick()', this);
this.setState({numOfClicks: this.state.numOfClicks + 1});
}
This should increment the value of state.numOfClicks
by 1. However, when the button is clicked, you will get this:

Again, the ‘this’ being referred to by setState()
is set to null
. Since the state is part of the App component, that is what ‘this’ should refer to. How do you change what ‘this’ refers to? Luckily Javascript has a few built-in methods that do exactly that.
The .bind() method
Every Javascript object has three built-in methods that can change the ‘this’ context for a function. The first two, .call()
and .apply()
are similar in that the first argument you pass to them is the new context and then you can pass them individual arguments or an array respectively. What they also have in common is that the function you call them on is then run immediately.
That won’t do in this case, since we want handleClick()
to only be run when the button is clicked. The third built-in Javascript method can do this.
The .bind()
method is similar to the other two in that you pass it the context you want to bind the function to, but it does not immediately run the function.
Instead a copy of the function with the switched context is returned.
This copy can then be run whenever you want. Like when a button is clicked.
The constructor way
Since the ‘this’ context of App is the one that handleClick()
should be using, we have to use the .bind()
method on it in the constructor for that component. If this line is added to the constructor, all will work as expected:
this.handleClick = this.handleClick.bind(this);
There are a lot of ‘this’ references in that line, so let’s break it down a bit.
The first this.handleClick
refers to the handleClick()
method. Since this is done in the constructor, ‘this’ refers to App.
The second this.handleClick
is also referring to the same handleClick()
method but we are now calling .bind()
on it.
The final ‘this’ is the context we are passing to .bind()
and it is referring to the App context.
So, we are setting the value of handleClick()
to equal the result of calling .bind()
on handleClick(),
and passing .bind()
the context of ‘this’ which refers to the App. This will have the result of making the context for handleClick()
be ‘App’ whenever it is called which is what we want since that is also where the ‘state’ is located and that is what we are trying to change.
Whew!
That’s a lot of words for one line of code. Here it is in action. The constructor now looks like this:
constructor(props) {
super(props);this.state = {
numOfClicks: 0
};this.handleClick = this.handleClick.bind(this);
}
And the app responds like this:

And just another sign that this is correct, here is what is logged to the console now.

Both of the ‘this’ keywords for .render()
and .handleClick()
now refer to the same thing.
The arrow function way
For those of you that would prefer to use arrow functions or if you just want to keep your constructors tidy, you can also use an ES6 arrow function to refer to any methods and this will have the same result.
The constructor has been set back to what it was originally
constructor(props) {
super(props);this.state = {
numOfClicks: 0
};
}
But now, I’ve added an arrow function to the onClick
prop of the button
<button onClick={() => this.handleClick()}>Click Me!</button>
The results are exactly the same as before. Arrow functions don’t define their own context so ‘this’ is set to the enclosing context. Which we can see from the console.log()
inside of render()
is already set to ‘App’.
Keeping track of ‘this’ can be tough as applications get more complex. It is often a stumbling block for those new and not so new to Javascript and React. Just remember that there are functions like bind()
to help you reassign the value of ‘this’ when needed. Thanks for reading and please leave any questions or comments below!