Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React event handler works without bind()

I'm working through a react tutorial and the instructor is showing that the event handler in this code won't work, because this() is accessing the outer environment. But I get no error. Can someone explain it to me?

import React, { Component } from "react";

class Counter extends Component {
  state = {
    count: 0,
  };

  handleIncrement() {
    console.log(this.state);
    console.log(this.props);
  }

  render() {
    return (
      <div>
        <button onClick={this.handleIncrement()}>
          Increment
        </button>
      </div>
    );
  }
}

export default Counter;
like image 227
Benedikt Hofírek Avatar asked Feb 07 '26 01:02

Benedikt Hofírek


2 Answers

The thing is, when your event handler needs to access this from a local scope, and you call the method like this; this.handleClick(), you are telling JavaScript to implement the task of the method IMMEDIATELY it gets there (in your case, immediately it is rendered), which conventionally, doesn't require binding to this.

But when you 'call' (I put it in quotations because the right word should be REFER) a method like this; this.handleClick, you are actually referring to the method (meaning it should be invoked only when the user does something), not invoking it immediately. This either requires binding this.handleClick= this.handleClick.bind(this); or the use of arrow function for your method handleClick = () => {};. It is mostly used for onClick functionalities.

You are not getting that error in your code because you included the parentheses - this.handleIncrement(). If you remove the parentheses and still consoleLog this.state in your handleIncrement, you will definitely get undefined error. But if your handleIncrement is only logging something outside a state, you will not get the error.

If you understand my basic explanation, kindly accept the answer.

like image 130
GeniusHawlah Avatar answered Feb 09 '26 15:02

GeniusHawlah


Any function called directly from render method will get the container object as this But when we assign a function to onClick event, we don't want to call that function immediately... so we assign it like this

<button onClick={this.handleIncrement}>

(only the function name without () at the end) ... and this says to call the function when the button is clicked.

But when you click the button the function will not be called from the render method anymore so the this reference will be changed and produce an error.

In your case, you added the () to your this.handleIncrement function invoking it immediately... so it's not causing any problem but it will give you wrong results in almost all cases since it won't get called on click but it will get called with each render.

Since your simple code gets rendered only on button click it's probably correcting the problem. Add a second button and it will give wrong result or the UI will freeze.

The correct way is to remove the () after this.handleIncreament and bind the function inside constructor ... this.handleIncreament = this.handleIncreament.bind(this)

like image 42
Afzal Hossain Avatar answered Feb 09 '26 17:02

Afzal Hossain



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!