最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - "this" is not defined in event handlers - Stack Overflow

programmeradmin1浏览0评论

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++;
}

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++;
}
Share Improve this question asked Apr 1, 2019 at 3:58 Sunil TripathiSunil Tripathi 6161 gold badge7 silver badges12 bronze badges 3
  • 2 Calling context is different. Try onClick={()=>this.increaseCounter()} or onClick={ this.increaseCounter.bind(this)} – charlietfl Commented Apr 1, 2019 at 4:01
  • 2 Possible duplicate of How to access the correct `this` inside a callback? – VLAZ Commented Apr 1, 2019 at 4:02
  • And don't assign to state like this.state.count++; instead use this.setState(prevState => ({count:prevState.count + 1})); – ivica.moke Commented Apr 1, 2019 at 7:49
Add a ment  | 

5 Answers 5

Reset to default 6

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./silesis/handle-events-in-react-with-arrow-functions-ede88184bbb#4803

When the interpreter reaches the ponent, 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.

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>

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.

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}
    }
}
发布评论

评论列表(0)

  1. 暂无评论