Reputation: 616
why this is not defined in function increaseCounter but is defined in getBadgeClass function ?
<button onClick = { this.increaseCounter } className = {
this.getBadgeClasses() }>increment</button>
getBadgeClasses() {
let classes = "badge m-2 badge-";
classes += this.state.count === 0 ? "warning" : "primary";
return classes;
}
increaseCounter(){
this.state.count++;
}
Upvotes: 1
Views: 2916
Reputation: 1
There are two parts to this error. The first is that the error handler must be defined like this, in order to make this
work correctly with the error function:
increaseCounter = () => { ... }
The second part of the problem is that you can't change the state directly; instead, you must change the state using this.setState()
:
increaseCounter = () => {
this.setState(prevState => {
return {count: prevState.count + 1}
}
}
Upvotes: 0
Reputation: 23
In addition to what Shahrukh has mentioned, in strict mode global object refers to undefined in place of the window object. So when the function increaseCounter() is called on global object, it calls on an undefined object.
Also, when a function is used as an event handler, its 'this' is set to the element the event fired from. As a DOM event handler. Therefore, increaseCounter()'s this is set to global context.
Since in JavaScript class methods are not bound by default unless you specifically bind them, they are just "function objects". Any object or variable can reference the function because it's just a pointer, like any other object.
The question asked is actually to be blamed on JavaScript, not React.js.
Upvotes: 0
Reputation: 141
You should bind function which uses this
. To save this
context you can use one of these ways:
1) Bind functions in the constructor:
constructor(props) {
super(props);
this.getBadgeClasses = this.getBadgeClasses.bind(this);
this.increaseCounter = this.increaseCounter.bind(this);
}
2) Or you can use arrow function. It saves this
context as well:
increaseCounter = () => {
...your code
}
You can read more here: https://medium.com/silesis/handle-events-in-react-with-arrow-functions-ede88184bbb#4803
Upvotes: 6
Reputation: 1896
you have to bind this
to increaseCounter
function to access this
object. Do this :
<button onClick = { this.increaseCounter.bind(this) }
className = { this.getBadgeClasses.bind(this) }
>
increment
</button>
Upvotes: 0
Reputation: 474
When the interpreter reaches the component, this.getBadgeClasses() executes right away. It is called on the object referred by this so the keyword this inside the function, points to the same object. So it is able to resolve the reference to the state.
On the other hand, this.increaseCounter() does not execute right away. The attribute onClick just stores a reference to that function. Whenever a user clicks on the button, that referenced function is called on the global object. So the keyword this is set to undefined in the strict mode. To resolve this, you have to bind the increaseCounter() to this in the constructor.
Upvotes: 1