Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - Cannot read property 'setState' of null [duplicate]

I'm aware theres similar threads that discuss the scoping issue.

Using the following component

import React from 'react';
import ReactDOM from 'react-dom';

class Example extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            counter: 0
        }
    }

    addMore() {
        this.setState({
            counter: this.state.counter + 1
        });
    }

    render() {
        return (

            <div onClick={ this.addMore }>
                <p>counter: { this.state.counter }</p>
            </div>

        );
    }
}

if (document.getElementById('example')) {
    ReactDOM.render(<Example />, document.getElementById('example'));
}

When you click the div you get Cannot read property 'setState' of null

I'm aware you can do things like this.addMore.bind(this) but all this seems weird extra boilerplate style code just to make it work.


What is considered the most elegant way to do this? As surely people must have a preferred way which have their benefits, other than being an eye sore?

like image 879
owenmelbz Avatar asked Apr 26 '17 21:04

owenmelbz


2 Answers

addMore = () => {
  this.setState({
    counter: this.state.counter + 1
  });
}

the arrow syntax takes care of the this binding for you

Check this great link for more information, it shows many ways to accomplish this http://egorsmirnov.me/2015/08/16/react-and-es6-part3.html

like image 198
Moe Avatar answered Oct 03 '22 08:10

Moe


You need to bind the correct this context to the function, and you can do that by adding this.addMore = this.addMore.bind(this); to the constructor function.

constructor(props) {
    super(props);

    this.state = {
        counter: 0
    }

    this.addMore = this.addMore.bind(this);
}

In the ES5 React.createClass all functions were automatically bound to the correct this but in ES6 class the correct this context isn't automatically bound. reference

This is called Bind in Constructor and this is the approach currently recommended in the React docs for “better performance in your application”. reference

like image 37
Amir5000 Avatar answered Oct 03 '22 08:10

Amir5000