“this.setstate is not a function” is a common error message that comes up in React. In this article, we’ll learn how to fix it.

As a reminder, we use this.setstate in React class components. If you’re using functional components, you’ll likely use the useState hook instead. You can learn more about the useState hook from this guide.

Let’s get started with an example. In our file App.js:

App.js
import { Element } from './Element' import './index.css' function App() { return ( <div> <Element/> </div> ); } export default App;

We use standard code, referencing Element from the file Element.js:

Element.js
import { Component, setState } from "react"; class Element extends Component { constructor ( props ) { super( props ); this.state = { value: 1 }; } handleClick() { this.setState({ value: 2 }); } render () { return ( <div style={{ padding: '5px' }} onClick={this.handleClick}> Value is: {this.state.value} </div> ) } } export { Element }

Theoretically, when we run our code, we should get a div in the browser that we can click to change the value from “1” to “2”. By using this.setState, we make the component instantly update when it is clicked and the value of the “value” variable changes.

With the above code, we get the following render in the browser:

However, when we click it, we get an error. We’ll get something like “this.setState is not a function” or “cannot read property ‘setState’ of undefined”. In either case, an error is thrown and our code stops working.

What went wrong? The answer lies in the keyword “this”.

Not Being able to Reference “this”

Let’s go back to where we set the “onClick” attribute for the <div> that gets rendered to the screen:

<div style={{ padding: '5px' }} onClick={this.handleClick}>

When we write the function this.handleClick, “this” ends up actually referring to the <div>, rather than our class component (which holds all the functions for the class). When the component is created, the handleClick function we defined earlier gets set to execute when the “click” event is fired.

Now, let’s take a look at the code inside the handleClick function:

handleClick() { this.setState({ value: 2 }); }

Now, our component has to execute the line of code:

this.setState({ value: 2 });

Without having any idea what this.setState is! The <div> that fires the “click” event has no idea where to find the function this.setState.

Where can we find this.setState then? The setState function is native to the React.Component class. Let’s look back at some code from Element.js:

class Element extends Component { constructor ( props ) { super( props ); this.state = { value: 1 }; }

Notice the “extends Component” above. When we call the super() function in the constructor method, Element inherits all attributes of the React.Component class, including setState.

In order for our <div> to be able to use the setState function, we need a way to bind the class we created with the DOM element that gets rendered to the screen. Fortunately, React has an extremely easy way to to this, using bind().

Let’s rewrite the component in Element.js:

Element.js
import { Component, setState } from "react"; class Element extends Component { constructor ( props ) { super( props ); this.state = { value: 1 }; } handleClick() { this.setState({ value: 2 }); } render () { return ( <div style={{ padding: '5px' }} onClick={this.handleClick.bind(this)}> Value is: {this.state.value} </div> ) } } export { Element }

Now, when we run our code, and click on the element that gets rendered to the browser, we get the following:

It worked this time because we connected the class we created with the DOM element we rendered to the screen. Thus, we can now reference “this” (the component’s class) and all its methods, including setState.

Using Arrow Functions

There’s actually another way to solve the problem which works just as well, using arrow functions. If you’re unfamiliar with them, here’s an explanation by the React authors.

In Element.js:

Element.js
import { Component } from "react"; class Element extends Component { constructor ( props ) { super( props ); this.state = { value: 1 }; } handleClick() { this.setState({ value: 2 }); } render () { return ( <div style={{ padding: '5px' }} onClick={() => {this.handleClick()}}> Value is: {this.state.value} </div> ) } } export { Element }

In the above code, all we change is the line corresponding to “onClick”. Instead of binding the function this.handleClick, we place it within an arrow function.

This essentially does the same thing as bind(), but by using an arrow function, React forms the connection between the class component and the DOM element for us. The arrow function causes the code reference to stay as we’ve written it, rather than disconnecting the class and the DOM element, and anything within the curly braces of the arrow function is able to reference “this” without errors.

Let’s test this code in the browser. When we click on the component, we get the following:

Conclusion

In this article we went over two ways to solve the React error message “this.setState is not a function”. If you have any questions or comments, feel free to leave them below!

Avatar photo
👋 Hey, I'm Jesse Ryan Shue
I am a Full-Stack Developer and an Industrial/Mechanical Designer. I have work experience in Industrial Design, 3D printing, and teaching. I am experienced in Python, JavaScript, and SolidWorks CAD. Follow me on LinkedIn

💬 Leave a comment

Your email address will not be published. Required fields are marked *

We will never share your email with anyone else.