Passing Functions to React Components

How do I pass an event handler to a component?

Nitai Aharoni 🎾
Better Programming
Published in
3 min readAug 4, 2020

--

Photo by Simone Hutsch on Unsplash.
<MyComponent onClick={this.handleClick}>

In React, there are several cases where you may want to pass a function (like onClick) as a prop from a container to a child component — usually in order to let the child notify the parent of some event.

For example:

A scenario where you have a CustomButton component that needs to change the counter state of its parent container component.

Assuming that you will probably need to have access to the parent component’s state or props from the child component, you will need to somehow bind the function to the parent component instance.

While there are a few ways to do that, some are better solutions.

How Do I Bind a Function to a Component Instance?

Depending on the syntax and build steps involved, there are many ways to ensure that functions have access to component attributes such as props and state.

1. Bind in constructor

While this a widely used method, it is a somewhat strange one that involves the use of the obscure word bind and requires an unnecessary line of code (we will discuss that later).

In my opinion, it is not the best way.

2. Bind in render

Although we supposedly save a line of code with this approach compared to the previous one, this method is still somewhat unclear and I do not recommend using it.

In addition, and perhaps more importantly:

“Using .bind(this) inside render, creates a new function each time the component renders, which may have performance implication.” — React’s documentation

3. Arrow function

An arrow function expression has a shorter syntax than a function expression and does not have its own this. For this reason, you can pass it to the child component and still access the parent’s props and state.

In my opinion, this is the best way:

Note: According to React’s documentation, “This syntax is experimental and not standardized yet.”

Passing Parameters to an Event Handler

Examine carefully if you really need to pass parameters through the function prop to the child.

Check if you have other options, such as passing the parameter as a prop or figuring out that you don’t really need the parameter in the child component.

Why am I saying this?

As mentioned before, using syntax like bind in render or an anonymous function (like in the next example) will cause the child component to re-render after each and every render of the parent — regardless of whether was changed is relevant to its child or not. That means poor performance.

As the child component receives an anonymous function as a prop, it cannot compare with the previous anonymous function (because both are anonymous). However, passing a reference to the method like
onClick={this.handleClick} lets React know that nothing has changed, so it does not re-render unnecessarily.

Example of what you shouldn’t do if you do not have to:

<button onClick={() => this.handleClick(id)} />

Note, however, that the anonymous function is sometimes inevitable (e.g. when we only need to pass an argument in the context).

Living proof

Check out the next CodeSandbox example. It demonstrates two ways of passing a function to a component as props. The first passes a function by reference, and the second passes an anonymous function.

When you click the button, the number near each of the components indicates how many times it was rendered.

Can you guess which one would render more times unnecessarily?

Finally, Make Sure You Aren’t Calling the Function When You Pass It to the Component

Don’t do this:

Code snippet by React.

Instead, pass the function itself (without parentheses):

Code snippet by React.

Conclusion

I hope this article helped you to understand how you can — and should — pass functions between components in a simple and efficient way.

Have a great day! Thanks for reading!

--

--

Nitai Aharoni 🎾
Nitai Aharoni 🎾

Written by Nitai Aharoni 🎾

A passionate full-stack developer. Playing with React ⚛, Node.js 🔫, Typescript 👾. Curious about all kinds of futuristic and green technologies ♻️🌱🌿.

Responses (1)

Write a response