So, you got the React error – cannot read property ‘setstate’ or ‘state’ or ‘props’ of undefined? Alright. Let’s see why it happens and how to solve it.
We use setState()
on this
as this.setState()
. So, setState
is the property of this
. The error says that React cannot read property ‘setstate’ of undefined, which means it is treating this
as undefined
.
In the same way, state
and props
are also the properties of this
. We use them like this.state.foo
or this.props.bar
.
Why it happens?
It happens because the methods inside a class doesn’t bind themselves within the context and we need to do it in constructor. So, this below code will create error –
import React from "react";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
flag: 1
};
}
onToggle(event) {
this.setState((prevState) => ({
flag: prevState.flag === 1 ? 0 : 1
}));
}
render() {
return (
<div className="App">
<p>Current Flag - {this.state.flag}</p>
<p>
<button onClick={this.onToggle}>Toggle Flag</button>
</p>
<p>
<em>
Button click will create{" "}
<b>React Error - cannot read property 'setstate' of undefined</b>
</em>
</p>
</div>
);
}
}
Check in live demo –
How to solve it?
There are two solutions for this –
- Bind the functions in constructor.
- Use ES6 arrow notation to declare functions.
To bind the function, use this code –
constructor(props){
this.onToggle = this.onToggle.bind(this);
}
To use ES6 arrow notation, use this code –
onToggle = (event) => {
// function body
}
Let’s check both of these in this code example –
import React from "react";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
flag: 1
};
this.onToggle = this.onToggle.bind(this);
}
onToggle(event) {
this.setState((prevState) => ({
flag: prevState.flag === 1 ? 0 : 1
}));
}
onToggle2 = (event) => {
this.setState((prevState) => ({
flag: prevState.flag === 1 ? 0 : 1
}));
};
render() {
return (
<div className="App">
<p>Current Flag - {this.state.flag}</p>
<p>
<button onClick={this.onToggle}>
Toggle Flag (Method bind in constructor)
</button>
</p>
<p>
<button onClick={this.onToggle2}>
Toggle Flag (Method using ES6 arrow notation)
</button>
</p>
</div>
);
}
}
Comments