[Solved] Uncaught TypeError: Cannot read property 'setState' of undefined - React JS

Article Ab Siddik

Hi, if you are a React developer, sometimes you feel helpless to develop your react app. Cause, you face some errors and you can't understand why it's happen.

I will try to help you to understand about those errors. In this article i will describe about "Uncaught TypeError: Cannot read property 'setState' of undefined" with an example.

App.js

import React, { Component } from 'react';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      msg: 'Hello'
    }
  }

  onSetDefaultMsgHandler() {
    this.setState({
      msg: 'Good Bye'
    });
  }



  render() {
    return (
      <div>
        <h1>{this.state.msg}</h1>
        <button onClick={this.onSetDefaultMsgHandler}>Default Message</button>
      </div>
    );
  }
}

export default App;

In App.js component, defined "msg" property in state and an event handler method to change this "msg" property value. And used a "p" tag to show the message from the state and used a button to change the message by event handler method. Now if we run the project we can't see any error, that's good. But if we click into button to change the message we can see the error. Now try to understand what's happend. In our event handler method we call this.setState method to change the state of this event. But we see that error message says us that setState is undefined. But we know that setState method previously defiend by React in Class component. But why the error showing us. Cause, we need to connect event handler to the component before the component mount. So we need to bind the event handler to the component. There are many ways to bind. i will try to show most of them and describe.

Firstly, we can bind our event handler in the constructor. 

  constructor(props) {
    super(props);
    this.state = {
      msg: 'Hello'
    };

    this.onSetDefaultMsgHandler = this.onSetDefaultMsgHandler.bind(this)  // Just Bind here
  }

Secondly, we can use bind method in render. 

  render() {
    return (
      <div>
        <h1>{this.state.msg}</h1>
        <button onClick={() => this.onSetDefaultMsgHandler}>Default Message</button>
      </div>
    );
  }

Thirdly, we can use an arrow function in the callback in render. But be careful must be use Parenthesis in event handler.

  render() {
    return (
      <div>
        <h1>{this.state.msg}</h1>
        <button onClick={() => this.onSetDefaultMsgHandler}>Default Message</button>
      </div>
    );
  }

Fourthly, we can change the event handler definition to arrow function.

  onSetDefaultMsgHandler = () => {
    this.setState({
      msg: 'Good Bye'
    });
  }