Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React.js: the most efficient way to pass a parameter to an event handler without bind() in a component

Tags:

When an event handler uses this (juet like handleClick below uses this.setState), you have to bind the event handler with this kerword. Otherwise, you need to use the arrow function.

e.g.

//This function isn't bound whilst using "this" keyword inside of it.
//Still, it works because it uses an arrow function
handleClick = () => {
    this.setState({
      isClicked:true
    });
}

render() {
    return (
      <div className="App">
        <button onClick={this.handleClick}>Click</button>
      </div>
    );
}

However, with the approach above, you can't pass a parameter. You need to use either...

  1. bind(this, param) after the function
  2. the anonymous arrow function

i.e.

<button onClick={this.handleClick}>Click</button>
will be
<button onClick={this.handleClick.bind(this, 111)}>Click</button>
or
<button onClick={() => this.handleClick(111)}>Click</button>

Here is the question.

What is the most efficient way to pass a parameter to an event handler?

According to the official doc, using bind() can undermine the performance, because...

Using Function.prototype.bind in render creates a new function each time the component renders

The same goes for using the anonymous arrow function. The doc says that...

Using an arrow function in render creates a new function each time the component renders

Then, what will be the most efficient way to pass a parameter?

Any input will be appreciated.

PS

Some people have asked how param is determined. This will be determined dynamically (i.e. not always 111). So, it can be from states, props or some other functions defined in this class.

like image 703
Hiroki Avatar asked Oct 13 '18 00:10

Hiroki


People also ask

How do you pass parameters to an event handler React?

Passing the event object of react as the second argument. If you want to pass a parameter to the click event handler you need to make use of the arrow function or bind the function. If you pass the argument directly the onClick function would be called automatically even before pressing the button.

How do you avoid the need for binding in React?

To avoid the need for binding we have something introduced in ES6 as arrow functions. Using the arrow function to call this. setState will lead to avoid the use of bind.

How do you pass an event handler to a component?

Passing Event Handler to Subcomponent The Address component is using the destructuring assignment { type, houseNo, clickHandler } to access the passed prop values directly. The clickHandler is a function to handle clicks, which is being passed to the onClick attribute.

Why do we need to bind event handlers in React?

Output: Now if we run the application and click on the button, we get an error. This is because this returns an “undefined”. This is why we need to bind our events. Binding Event Handler in Render Method: We can bind the handler when it is called in the render method using bind() method.


1 Answers

Instead of .binding or creating an anonymous arrow function in render(), you can create the bound/anonymous function outside of render(), such as on the instantiated object, in the constructor, or something like that, and use a reference to that singular (never re-created) function. For example, run once:

this.boundHandleClick = this.handleClick.bind(this, 111);

or

this.boundHandleClick = () => this.handleClick(111);

Then, in render, reference boundHandleClick:

return (
  <div className="App">
    <button onClick={this.boundHandleClick}>Click</button>
  </div>
);

If you need to use the parameters (111) inside of render, then you could use object lookup to see if a bound function with that parameter exists yet. If it does, just use that bound function - else, create it (once, so it won't have to be created again whenever you use that parameter in the future):

this.boundClicks = {};
// ...
if (!this.boundClicks['111']) this.boundClicks['111'] = () => this.handleClick(111);
return (
  <div className="App">
    <button onClick={this.boundClicks['111']}>Click</button>
  </div>
);
like image 119
CertainPerformance Avatar answered Sep 29 '22 21:09

CertainPerformance