Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

253
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda