简体   繁体   中英

When to use inline function on button onClick event - Javascript/React.js

I can see different style of assigning event handler to the button onClick event. Can anyone suggest when to use inline function on button onClick event handler?

onClick={props.handleDeleteOption(props.optionText)}; // Call the handler directly

onClick={(e) => {
          props.handleDeleteOption(props.optionText);
        }} // Call the handler through inline-function

Performance

Whether or not you use inline event handler functions it has an impact on the performance of the app.

Inline event handlers are anonymous functions. They are created every time the component renders. That is, every time you call setState or when the component receives new props.

Whenever a component is about to be rendered (when the state has been updated or receives new props,) react performs a shallow comparison between the previous DOM and the new DOM for that component. If they are found to have different props from the props before the state update, then the component will re-render that particular component and all its child components. If not, it assumes the component is the same as the old DOM and so it doesn't render it.

Now inline functions are objects (functions are objects in javascript.) And when react compares functions, it does a strict comparison. The inline function might not have changed in its value, but it is an entirely different function (different reference in memory) and so React detects that there has been a change. And when there is a change, React re-renders the component and all its children.

Again, let me just state that performance decisions are usually largely tradeoffs. This explanation doesn't mean that you should remove all inline event handlers and define them at the class level. This can slow down the first render for your component because of the binding that has to be done in the constructor. There is also this thing called premature optimization which can lead to poor quality of code or it just might not be worth it.

According to the ReactJS documentation:

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>

<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

The above two lines are equivalent, and use arrow functions and Function.prototype.bind respectively.

In both cases, the e argument representing the React event will be passed as a second argument after the ID. With an arrow function, we have to pass it explicitly, but with bind any further arguments are automatically forwarded.

This can be found at the bottom of this link: https://reactjs.org/docs/handling-events.html

The main difference is about how you wrote your function. Examples from documentation :

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>
    );
  }
}

And the second one:

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>
    );
  }
}

But as you can read in documentation, second approach is worse from performance perspective.

onClick={props.handleDeleteOption(props.optionText)}; this will cause props.handleDeleteOption(props.optionText)} to be called without clicking the button.

In javascript, let there be a function called foo , foo() will call the function whereas foo itself will be the reference to that function.

So when you do as in the second case, the function is passed to the onClick handler and will be triggered only onClick . The first line of code will not work as expected since it is being called there itself. If you did not have to pass any data to the function, you could also have had written onClick={props.handleDeleteOption} (notice there are no brackets), and that would work as expected.

But since there is data, the only way you can write it is by onClick={(e) => {props.handleDeleteOption(props.optionText)}}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM