Understanding "this" in React
— JavaScript, React — 2 min read
this
in JavaScript can confusing as it can change based on where it is called from. In this post I'll try to clear it up.
The JavaScript "this" keyword refers to the object it belongs to. 1
To clearly understand how this
can change let's look at the places it can be called from.
"this" alone
this
accessed outside a function will return the global variable.
"this" in a function
If we access this
inside a function (cannot be a method), it'll be the global variable and in "strict mode" it'll be undefined
.
"this" in a method
When this
is accessed in a method, it refers to the owner of the method, which is the object it's in.
"this" in an inner function
Here this
changes inside testFunction()
. In order to understand why we need to know how scope applies to this
.
Unlike variables, the this keyword does not have a scope, and nested functions do not inherit the this value of their caller. If a nested function is invoked as a method, its this value is the object it was invoked on. 2
This means that the this
of testFunction()
is not aware of the user
object so it returns undefined
for this.firstName
and this.lastName
.
So how do we get the proper "this" into the inner function?
Before ES5
Before ES5 there was no proper way to pass this
to inner functions. The example shown around is a workaround. 3
ES5
ES5 introduced the bind
method, which allows us to set the this
of the function. So after we run the line testFunction = testFunction.bind(this)
, the this
of testFunction()
becomes the user
object.
ES6+
ES6 brought us arrow functions, which automatically binds this
to the function, which leads to less and cleaner code.
So what about React?
Consider the following code.
It'll fail once we click the button and code reaches the this.setState({ text: "Hello World!" });
line. Why? Because at that point this
will be undefined
. this
wasn't implicitly bound to setText()
so it defaults to the global variable which in this case is undefined
because classes run in "strict mode". Since this
wasn't implicitly bound, we need to explicitly bind this
to setText()
.
We could solve this by using the way we did it the before ES5 example but that's stringly discouraged. If we did it with bind
, it would look like this.
If you use bind
, you'll have to do it in the constructor.
Arrow functions can make it easier by just needing to change setText()
to an arrow function.
References
- w3schools.com, The JavaScript this Keyword.↩
- David Flanagan, JavaScript: The Definitive Guide↩
- amitai, Using "this" in react functions↩