Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

263
Views
React - Why is binding this not required in this example?

Trying to figure out the basics of React.

Looking at the second example on this page: https://facebook.github.io/react/ I see that the tick() function sets the state of the Timer class, incrementing the previous value by one.

class Timer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {secondsElapsed: 0};
  }

  tick() {
    this.setState((prevState) => ({
      secondsElapsed: prevState.secondsElapsed + 1
    }));
  }

  componentDidMount() {
    this.interval = setInterval(() => this.tick(), 1000);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    return (
      <div>Seconds Elapsed: {this.state.secondsElapsed}</div>
    );
  }
}

ReactDOM.render(<Timer />, mountNode);

However, when I tried to implement my own simple Counter class, it failed and I got a console error saying Cannot read property setState of undefined.

class Counter extends React.Component {
    constructor(props) {
        super(props);
        this.state = {count: 0};
    }

    increment(prevState) {
        this.setState((prevState) => ({
            count: prevState.count + 1
        }));
    }

  render() {
    return (
            <div className="main">
                <button onClick={this.increment}>{this.state.count}</button>
            </div>
    )
  }
}

Some Googling reveals that I have to bind this to the increment function. But why was that not required in the first example that I saw? I copied the code to CodePen and it ran fine with React 15.3.1 I cannot find anything resembling binding in that example. Only after I added binding code in the constructor did things start working in my example.

class Counter extends React.Component {
    constructor(props) {
        super(props);
        this.state = {count: 0};

        // THIS ONE LINE FIXED THE ISSUE
        this.increment = this.increment.bind(this);
    }

    increment(prevState) {
        this.setState((prevState) => ({
      count: prevState.count + 1
    }));
    }

  render() {
    return (
            <div className="main">
                <button onClick={this.increment}>{this.state.count}</button>
            </div>
    )
  }
}
over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Answering your question: the first example uses arrow functions, that automatically performs context binding. From the docs:

An arrow function does not create its own this context, so this has its original meaning from the enclosing context.

Indeed there are some ways of binding in React:

1) you can bind all functions in your constructor, like you said:

constructor(props) {
    /* ... */
    this.increment = this.increment.bind(this);
}

2) invoke your callbacks with arrow functions:

<button onClick={(e) => this.increment(e)}>

3) append .bind at the end of your method reference each time you set it as a callback, like this:

<button onClick={this.increment.bind(this)}>

4) In your class, define the method with arrow functions:

increment = (e) => {
  /* your class function defined as ES6 arrow function */
}

/* ... */

<button onClick={this.increment}>

In order to use this syntax with babel, you have to enable this plugin or use stage-2 preset.

over 4 years ago · Santiago Trujillo Report

0

If you look closely at the way the tick() function has been called in your fist example, you will understand that binding has been specified to it when it is called using the arrow functions. If you do the same for the increment function it will also work. These are just different ways of binding the functions.

So as asked, its not that in the first example no binding is specified while the second it requires, rather in both your cases you are binding just that the way of binding is different for both the cases.

class Counter extends React.Component {
    constructor(props) {
        super(props);
        this.state = {count: 0};

        
       
    }

    increment(prevState) {
        this.setState((prevState) => ({
      count: prevState.count + 1
    }));
    }

  render() {
    return (
            <div className="main">
                <button onClick={() => this.increment()}>{this.state.count}</button>
            </div>
    )
  }
}

ReactDOM.render(<Counter/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!