0

I'm exploring option on how is the most elegant/readable way to pass parameters to a React class method without compromising on performance.

Let's say I have two Arrow components to switch between items. Each Arrow listen for click event and trigger a state change on the parent depending on the direction.

The first option is to pass each Arrow component an arrow function as the onClick handler with the corresponding direction:

  switchItem = dir => {
    this.setState(pv => ({ item: (pv.item += dir) }));
  };


  <Arrow left onClick={() => this.switchItem(-1)} />
  <Arrow right onClick={() => this.switchItem(1)} />

This is quite elegant but cause performance issue due to the function being re-created at each render. The same problem apply to currying.

So the second option is to declare a specific handler for each case:

  previousItem = () => {
    this.setState(pv => ({ item: (pv.item -= 1) }));
  };

  nextItem = () => {
    this.setState(pv => ({ item: (pv.item += 1) }));
  };

  <Arrow left onClick={this.previousItem} />
  <Arrow right onClick={this.nextItem} />

This cause no performance issue but is very verbose and not very reusable (what if we have 10 different arrows with 10 different directions)

Is there other (better) options for doing that ? If not what should be the preferred way ?

Thanks !

Théo Champion
  • 1,701
  • 1
  • 21
  • 46

2 Answers2

1

As stated in this answer you can either use the arrow functions (the performance problems will usually be unnoticeable) or do it the React way: creating a new component or modifying the one you have. In this case, you could change your Arrow Component so that the handler function of the component calls the function you send it with an itemValue that you also provide as a prop:

  <Arrow left onClick={this.switchItem} itemValue={-1} />

Then, in the Arrow Component you could do something like this in the function where you handle the click:

  handleClick = () => {
    this.props.onClick(this.props.itemValue);
  }

This is a more elegant and reusable solution than the second one that you proposed and the performance would be great. However, I would probably stick to the arrow function unless you know that many components will be rendered.

César Landesa
  • 2,626
  • 1
  • 13
  • 18
  • I explored this options too, however this prevent `Arrow` from being a stateless functional component – Théo Champion May 21 '18 at 10:28
  • 1
    It can be completely stateless anyway, since this function only depends on props! You could also create a wrapper component for the Arrow component with this logic in case you don't want it to be there for whatever reason. – César Landesa May 21 '18 at 10:29
  • The performance would be great anyway. There is no performance issue in the original post in the first place. The OP is just creating a problem that doesn't exist. This is just adding more bloat to a code that doesn't need it. Also, if you're creating another component, then at least make two separate - `ArrowLeft` and `ArrowRight` with logic and appearance encapsulated in them. That way, you don't need to pass 3 props to each of them, but only one. – Jan Kalfus May 21 '18 at 11:23
  • @HonzaKalfus What do you mean no performance issue ? No perceptible performance issue or not at all ? – Théo Champion May 21 '18 at 12:40
  • @ThéoChampion No perceptible issue. Your code will be probably like a few microseconds slower. You shouldn't really worry about it and focus on writing a code that's readable instead ;) – Jan Kalfus May 21 '18 at 14:59
0

Unless you're rendering the Arrow components a million times per second, you need not worry about performance. Use whatever is convenient to you. Put readability first. Code is written once, but read over and over many times.

Jan Kalfus
  • 5,422
  • 2
  • 30
  • 38