0

There are different ways of defining event handlers in ReactJS component with JSX syntax.

<input onChange={this.handleChange.bind(this)}></input>  // inline binding

And

<input onChange={() => this.handleChange()}></input>  // using arrow function

Both allow handleChange function to access this scope of component.

I have been using the first syntax as it is more clear in readability.

Are there any advantages or use cases to use one over another?

Venkat Ch
  • 1,168
  • 2
  • 17
  • 37

2 Answers2

3

From the React Docs

class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // This syntax ensures `this` is bound within handleClick
    return (
      <button onClick={(e) => this.handleClick(e)}>
        Click me
      </button>
    );
  }
}

The problem with this syntax is that a different callback is created each time the LoggingButton renders. In most cases, this is fine. However, if this callback is passed as a prop to lower components, those components might do an extra re-rendering. We generally recommend binding in the constructor or using the property initializer syntax, to avoid this sort of performance problem.

So, you should use bind and you can do that in two ways.

From the React Docs

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

and if bind annoys you, then you can do it like this

class LoggingButton extends React.Component {
  // This syntax ensures `this` is bound within handleClick.
  // Warning: this is *experimental* syntax.
  handleClick = () => {
    console.log('this is:', this);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}

The only advantage that I can think of for using one over the other is that in the top approach you can pass parameters to the handleClick function. But I can't think of a situation on where you might do that.

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};
  }

  handleClick(e, something) {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
    alert(something)
  }

  render() {
    return (
      <button onClick={(e) => this.handleClick(e, "Yo!")}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

ReactDOM.render(
  <Toggle />,
  document.getElementById('root')
);
Lavios
  • 1,169
  • 10
  • 22
1

You can bind functions in the constructor:

constructor(){
    super();
    this.handleChange= this.handleChange.bind(this);
}

But the best way is define your method with arrow function:

handleChange = () => {}

In this variant you will run bind each time when component will render:

<input onChange={this.handleChange.bind(this)}></input>

Arrow function is used when you need to pass something to your method:

<input onChange={() => this.handleChange(params)}></input>

Because:

<input onChange={this.handleChange(params)}></input>

Will fire when component will render.

Check this arcticle.

Andrii Starusiev
  • 7,564
  • 2
  • 28
  • 37