6

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?

owenmelbz
  • 6,180
  • 16
  • 63
  • 113

2 Answers2

21
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

Moe
  • 3,467
  • 1
  • 19
  • 25
9

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

Amir5000
  • 1,718
  • 15
  • 19