When you first start to write React components, you might encounter several different errors along the way. Two such errors are “Cannot read property ‘setState’ of undefined” and “this.setState is not a function”. This article takes a look at a couple of ways to make these errors go away.
Why?
These errors occur because the method you are using or invoking in your React Component is not bound correctly. Here is an example of code that will cause the error to happen (This assumes that you have your React component set up correctly):
import React from "react"; import "./styles.css"; class App extends React.Component { constructor(props) { super(props); this.state = { input: "" }; } handleChange(e) { this.setState({[e.target.name]: e.target.value}) } render() { console.log(this.state) return ( <div className="App"> <h1>Sample React Application</h1> <input name="input" onChange={this.handleChange} value={this.state.input} type="text" placeholder="Type here..."/> <input type="submit" /> </div> ); } } export default App;
At first glance, the code looks all right, but if we look closer, we see the handleChange method is not bound to the App class so the “this” keyword will refer to the Window in this instance. To take a closer look, let’s add a console.log(this)to both the first line of the handleChange method and then to the first line of the render:
handleChange(e) { console.log(this, "change") this.setState({[e.target.name]: e.target.value}) }
render() { console.log(this, "render") return ( <div className="App"> <h1>Sample React Application</h1> <input name="input" onChange={this.handleChange} value={this.state.input} type="text" placeholder="Type here..."/> <input type="submit" /> </div> ); }
If we take a look at the console when we load the application, we will see that the “this” keyword refers to App. If we try to use our input, we get an error on screen, but if we look at the console, we will see that the “this” keyword there refers to the Window Object, not App. There are two ways to fix this problem:
1. Bind The Method
Inside the constructor, after the state object, input this line:
this.handleChange = this.handleChange.bind(this);
This line will bind the “this” keyword to the handleChange method so it can explicitly refer to the App component when invoking the handleChange. Otherwise, the method doesn’t know or see the component you want it to work with.
2. ES6 Arrow Function
Use the ES6 syntax for the big arrow function. It automatically binds the “this” keyword to that method so you don’t have to bind it in the constructor:
handleChange = (e) => { this.setState({[e.target.name]: e.target.value}) }
There you have it! That’s how you get rid of the “this.setState” is “undefined” or “not a function” error when using the class component structure in React. If you would like to prevent these errors in the future, refactor your React component to using functional components with React Hooks instead!
About us: Career Karma is a platform designed to help job seekers find, research, and connect with job training programs to advance their careers. Learn about the CK publication.