anthony-dandrea
anthony-dandrea

Reputation: 2813

React performance and passing down arrow functions as props

I've recently learned that passing down object literals or functions as props can cause unnecessary re-renders. As I am doing an audit on my app, I am finding some cases where I have common components that have callbacks on events that do different things. It's unclear to me what the most elegant way to handle this would be.

So for example in my app I have a component called SharedBtn that is used all over the app multiple places and in large loops. This button has an onClick listener. But in every instance this onClick is used we are passing down a different function to do a different thing every time.

Example: https://codesandbox.io/s/k31120vnyo

I read this related article with examples. But their solution is to move the onClick logic to the shared component. This would be ugly for me as it is used in many different spots with many different handlers. How could I have the multiple click handlers without moving the click handling logic to the SharedBtn component itself?

Upvotes: 0

Views: 436

Answers (2)

anthony-dandrea
anthony-dandrea

Reputation: 2813

Most of the time the performance hit is negligible. But the correct way to mitigate this in the age of hooks is via useCallback.

import { useCallback } from "react"
const MyComp = () => {
  const func = useCallback(() => doSomething(), []);
  return <OtherComp func={func}/>
};

Upvotes: 0

Alex Guerra
Alex Guerra

Reputation: 2736

You could create a small wrapper component for each special instance.

class IndexSharedButton extends React.PureComponent {
  handleClick = e => {
    this.props.onClick(e, this.props.index);
  };
  render() {
    return <SharedBtn copy={this.props.copy} onClick={this.handleClick} />;
  }
}

class AnimalSharedButton extends React.PureComponent {
  handleClick = e => {
    this.props.onClick(this.props.animal, this.props.type);
  };
  render() {
    return (
      <SharedBtn copy={this.props.animal} onClick={this.handleClick} />
    );
  }
}

You could also manually manage caching the bound handlers, but IMO that's pretty ugly and much less idiomatic.

Also, I think it goes without saying that you shouldn't worry about this much at all if you haven't measured it to be an actual issue. Re-renders don't happen that often, and with shouldComponentUpdate should happen even less. Optimizations like this add more code for little benefit.

Upvotes: 1

Related Questions