Cannot read property 'setState' of undefined in React.js

avatar
Borislav Hadzhiev

Last updated: Apr 6, 2024
2 min

banner

# Cannot read property 'setState' of undefined in React.js

The "Cannot read property 'setState' of undefined" error occurs when a class method is called without having the correct context bound to the this keyword.

To solve the error, define the class method as an arrow function or use the bind method in the classes' constructor method.

typeerror cannot read property setstate of undefined

shell
Uncaught TypeError: Cannot read properties of undefined (reading 'setState')

Here is an example of how the error occurs.

App.js
import React, {Component} from 'react'; class App extends Component { constructor(props) { super(props); this.state = { isActive: false, }; } toggleIsActive() { // ⛔️ `this` is undefined here // Uncaught TypeError: Cannot read properties of undefined (reading 'setState') this.setState({isActive: !this.state.isActive}); } render() { console.log(this.state.isActive); return ( <div> <button onClick={this.toggleIsActive}>Toggle</button> </div> ); } } export default App;
The code for this article is available on GitHub

Notice that we defined the toggleIsActive method, but we haven't bound the context of the this keyword.

Therefore, the this keyword in the toggleIsActive method has a value of undefined.

To solve the error, switch the toggleIsActive method to use an arrow function instead.

index.js
import React, {Component} from 'react'; class App extends Component { constructor(props) { super(props); this.state = { isActive: false, }; } // ✅ Works because we used an arrow function // to declare the method toggleIsActive = () => { this.setState({isActive: !this.state.isActive}); }; render() { console.log(this.state.isActive); return ( <div> <button onClick={this.toggleIsActive}>Toggle</button> </div> ); } } export default App;

switch method to use arrow function

The code for this article is available on GitHub

This works because arrow functions use the this keyword of the enclosing scope - in our example, the enclosing scope is the specific component instance.

Alternatively, you can call the Function.bind() method in the class's constructor.

App.js
import React, {Component} from 'react'; class App extends Component { constructor(props) { super(props); this.state = { isActive: false, }; // ✅ Bind method here this.toggleIsActive = this.toggleIsActive.bind(this); } // ✅ Works toggleIsActive() { // ✅ `this` is correctly bound here this.setState({isActive: !this.state.isActive}); } render() { console.log(this.state.isActive); return ( <div> <button onClick={this.toggleIsActive}>Toggle</button> </div> ); } } export default App;

using function bind method

The code for this article is available on GitHub

The bind method creates and returns a new function where the this keyword is set to the provided value.

The this keyword in the constructor refers to the class instance.

This is the case when working in classes in vanilla JavaScript as well.

index.js
class Person { constructor(first, last) { this.first = first; this.last = last; console.log(this); // 👉️ {first: 'James', last: 'Doe'} } } const p1 = new Person('James', 'Doe');

This enables us to bind the method in the constructor and use the bound version throughout the class.

My preferred approach is to use arrow functions to define my class methods when possible. This way I don't have to think about the this keyword and everything just works by default.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.