-1

Suppose the component below is instantiated a thousand times (I'm not talking about one instantiation being re-rendered a thousand times):

class TableRow extends Component {
  render() {
    return (
      <tr onClick={() => {console.log('You clicked this table row!');}}>
        <td>foo</td>
        <td>bar</td>
      </tr>
    );
  }
}

If the onClick function is only created when actual click happens, then I'll stop worrying. But if it's created a thousand times, I'll want to move it into the prototype, which is going to be ugly.

(I know if I put it into the class field, like handleClick = {console.log('You clicked this table row!)}, it'll definitely be slow, because it's compiled into the constructor. But is the inline pattern any faster?)

ZYinMD
  • 3,602
  • 1
  • 23
  • 32
  • 1
    Obviously, the function is created during render. And you should not really worry unless you have a performance problem. The second part of you question about "class field" does not make much sense. – Sulthan Mar 02 '19 at 18:31
  • Take a look at this question and answer for detailed explanation https://stackoverflow.com/questions/52031147/react-which-is-recommended-arrow-or-normal-function – Hemadri Dasari Mar 02 '19 at 18:47
  • Why would moving it to the prototype be ugly? – P Varga Mar 03 '19 at 01:04

4 Answers4

1

Yes, it's created on every render. The handleClick approach will only create it once and use the same function every time.

jorbuedo
  • 2,041
  • 1
  • 8
  • 20
1

The problem with this syntax is that a different callback is created each time the TableRow renders. 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. For more info

Umair Farooq
  • 1,763
  • 13
  • 16
1

From the React documentation

Using an arrow function in render creates a new function each time the component renders, which may have performance implications (see below).

Dor Shinar
  • 1,474
  • 2
  • 11
  • 17
1

Just try it™️

let counter = 0; const a = [1,2,3];
class Comp1 extends React.Component {
  render() {
    return a.map(v => <tr onClick={l(1), () => console.log('You clicked this row')}>Row {v}</tr>);
  }
}
class Comp2 extends React.Component {
  handleClick = (l(2), () => console.log('You clicked this row'));
  render() {
    return a.map(v => <tr onClick={this.handleClick}>Row {v}</tr>);
  }
}
ReactDOM.render([<Comp1/>, <Comp2/>], document.querySelector('main'));

/** Log function creation */
function l(n) {
  console.warn(`${++counter}: Creating function #${n}`);
}
<script src="//cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<main></main>
P Varga
  • 19,174
  • 12
  • 70
  • 108