13

You're not supposed to use anonymous functions in react attributes, e.g.

<a onClick=()=>doIt('myId')>Aaron</a>

I understand why this creates a performance problem for React's reconciliation because that anonymous function is recreated on every render pass and will thus always trigger a real DOM re-render of some kind. My question is, for a small component (i.e. not table where every row has a link) is this insignificant? I mean, React is smart enough just to replace the handler, not to re-render the DOM, right? so the cost is not that high?

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
CpnAhab
  • 159
  • 1
  • 1
  • 6

3 Answers3

9

I feel obliged to inform you that using an Anonymous function and Function.bind(this) in the render triggers a new render. This is because both

doIt.bind(this, 'myId') === doIt.bind(this, 'myId') // false

AND

() => doIt('myId') === () => doIt('myId') // false  

are FALSE!

If you want to bind something to a function, use partial application with a method in the React class.

class myComponent extends Component {

  doIt = (id) => () => {
    // Do Something
  }

  render() {
    <div>
      <a onClick={this.doIt('myId')}>Aaron</a>
    </div>
  }
}
Craig1123
  • 1,510
  • 2
  • 17
  • 25
  • 1
    using arrow functions inside class are translated under the hood to a property of that class so inhereted instances are creating a new property of the same function, but when using a normal class method like doIt() {}, it will be added to class prototype which will be shared among the instance of that class, that's why I think using arrow functions would affect the performance in a negative way for some use cases. and here is a link for explaining that https://medium.com/@charpeni/arrow-functions-in-class-properties-might-not-be-as-great-as-we-think-3b3551c440b1 – Muho May 03 '19 at 15:45
  • This answer contains the **WHY**!! Using arrow function leads to **re-rendering** the component and its children. Thanks for the answer. Just what i was looking for. – Gr3at Nov 23 '21 at 15:36
4

For:

  • small components: you are ok (almost no performance issues)
  • large components: the deeper you get the more try to avoid it

In React documentation about event handling, you can find:

In most cases, this is fine. However, if this callback is passed as a prop to lower components, those components might do an extra re-rendering. We generally recommend binding in the constructor or using the class fields syntax, to avoid this sort of performance problem.


Note: React is not handling callback props differently than other props. It always compares the old and new prop. Thus it re-renders when anonymous function is present because the anonymous function is always newly created.

exmaxx
  • 3,252
  • 28
  • 27
0

Your JSX code sample should actually look like this:

<a onClick={ ()=>doIt('myId') }>Aaron</a>

Using an anonymous fat arrow function like this is perfectly valid. You are supposed to use anonymous functions in react attributes. That's okay.

Yes, it's not a best practice. If you want to solve the this context issue when using the ES6 class extends React.Component syntax I would advise you to bind the function in the class constructor.

No, for a 'small' component (i.e. not table where every row has a link) this is not a significant performance issue. You are safe.

Kaloyan Kosev
  • 12,483
  • 8
  • 59
  • 90