I am getting the following error
Uncaught TypeError: Cannot read property \'setState\' of undefined
even after binding delta in
There are two solutions of this issue:
The first solution is add a constructor to your component and bind your function like bellow:
constructor(props) {
super(props);
...
this.delta = this.delta.bind(this);
}
So do this:
this.delta = this.delta.bind(this);
Instead of this:
this.delta.bind(this);
The second solution is to use an arrow function instead:
delta = () => {
this.setState({
count : this.state.count++
});
}
Actually arrow function DOES NOT bind it’s own this
. Arrow Functions lexically bind
their context so this
actually refers to the originating context.
For more information about bind function:
Bind function Understanding JavaScript Bind ()
For more information about arrow function:
Javascript ES6 — Arrow Functions and Lexical this
This error can be resolved by various methods-
If you are using ES5 syntax, then as per React js Documentation you have to use bind method.
Something like this for the above example:
this.delta = this.delta.bind(this)
If you are using ES6 syntax,then you need not use bind method,you can do it with something like this:
delta=()=>{
this.setState({
count : this.state.count++
});
}
You can also use:
<button onClick={()=>this.delta()}>+</button>
Or:
<button onClick={event=>this.delta(event)}>+</button>
If you are passing some params..
You have to bind your methods with 'this' (default object). So whatever your function may be just bind that in the constructor.
constructor(props) {
super(props);
this.state = { checked:false };
this.handleChecked = this.handleChecked.bind(this);
}
handleChecked(){
this.setState({
checked: !(this.state.checked)
})
}
render(){
var msg;
if(this.state.checked){
msg = 'checked'
}
else{
msg = 'not checked'
}
return (
<div>
<input type='checkbox' defaultChecked = {this.state.checked} onChange = {this.handleChecked} />
<h3>This is {msg}</h3>
</div>
);
though this question had a solution already, I just want to share mine to make it be cleared, hope it could help:
/*
* The root cause is method doesn't in the App's context
* so that it can't access other attributes of "this".
* Below are few ways to define App's method property
*/
class App extends React.Component {
constructor() {
this.sayHi = 'hello';
// create method inside constructor, context = this
this.method = ()=> { console.log(this.sayHi) };
// bind method1 in constructor into context 'this'
this.method1 = this.method.bind(this)
}
// method1 was defined here
method1() {
console.log(this.sayHi);
}
// create method property by arrow function. I recommend this.
method2 = () => {
console.log(this.sayHi);
}
render() {
//....
}
}
There is a difference of context between ES5 and ES6 class. So, there will be a little difference between the implementations as well.
Here is the ES5 version:
var Counter = React.createClass({
getInitialState: function() { return { count : 1 }; },
delta: function() {
this.setState({
count : this.state.count++
});
},
render: function() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta}>+</button>
</div>
);
}
});
and here is the ES6 version:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count : 1 };
}
delta() {
this.setState({
count : this.state.count++
});
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta.bind(this)}>+</button>
</div>
);
}
}
Just be careful, beside the syntax difference in the class implementation, there is a difference in the event handler binding.
In the ES5 version, it's
<button onClick={this.delta}>+</button>
In the ES6 version, it's:
<button onClick={this.delta.bind(this)}>+</button>