Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - uncaught TypeError: Cannot read property 'setState' of undefined

I am getting the following error

Uncaught TypeError: Cannot read property 'setState' of undefined

even after binding delta in the constructor.

class Counter extends React.Component {     constructor(props) {         super(props);          this.state = {             count : 1         };          this.delta.bind(this);     }      delta() {         this.setState({             count : this.state.count++         });     }      render() {         return (             <div>                 <h1>{this.state.count}</h1>                 <button onClick={this.delta}>+</button>             </div>         );     } } 
like image 631
Dangling_pointer Avatar asked Aug 31 '15 18:08

Dangling_pointer


People also ask

What does Cannot read property of undefined mean?

What Causes TypeError: Cannot Read Property of Undefined. Undefined means that a variable has been declared but has not been assigned a value. In JavaScript, properties and functions can only belong to objects.

How do I use setState in React class component?

The setState() Method State can be updated in response to event handlers, server responses, or prop changes. This is done using the setState() method. The setState() method enqueues all of the updates made to the component state and instructs React to re-render the component and its children with the updated state.

Can we use setState in functional component?

useState returns the current state and a function to update it. But this function updates the value in an asynchronous way. That means by calling that function, the variable is not going to change immediately.

How do you bind in React?

ReactJS bind() MethodThe bind() is an inbuilt method in React that is used to pass the data as an argument to the function of a class based component. Syntax: this. function.


2 Answers

This is due to this.delta not being bound to this.

In order to bind set this.delta = this.delta.bind(this) in the constructor:

constructor(props) {     super(props);      this.state = {         count : 1     };      this.delta = this.delta.bind(this); } 

Currently, you are calling bind. But bind returns a bound function. You need to set the function to its bound value.

like image 101
Davin Tryon Avatar answered Sep 30 '22 16:09

Davin Tryon


In ES7+ (ES2016) you can use the experimental function bind syntax operator :: to bind. It is a syntactic sugar and will do the same as Davin Tryon's answer.

You can then rewrite this.delta = this.delta.bind(this); to this.delta = ::this.delta;


For ES6+ (ES2015) you can also use the ES6+ arrow function (=>) to be able to use this.

delta = () => {     this.setState({         count : this.state.count + 1     }); } 

Why ? From the Mozilla doc :

Until arrow functions, every new function defined its own this value [...]. This proved to be annoying with an object-oriented style of programming.

Arrow functions capture the this value of the enclosing context [...]

like image 24
Fabien Sa Avatar answered Sep 30 '22 14:09

Fabien Sa