skip to Main Content

Consider these two components:

function App1 () {
    return <button onClick={() => null}>Click me</button>
}
function App2 () {
    const fn = () => null;
    return <button onClick={fn}>Click me</button>
}

Only difference is the click handler is defined inline in the first case, and extracted in a function in the latter.

I’ve always thought these snippets behave exaclty the same way.
The only way I could imagine this not being the case is if JSX transpilation alters the outputs, but it doesn’t seem the case

Today I’ve been told that in App1 the inline function is created every time the component re-renders, but this doesn’t happen in App2. This also obtained initial confirmation by ChatGPT:

[ChatGPT]
In App1, the arrow function is directly declared inside the onClick attribute. 
This means that a new function instance is created each time the component re-renders.

In App2, the arrow function fn is declared outside of the render function and then passed as a reference to the onClick attribute. 
This means that the same function instance is used across re-renders.

But this seems wrong: it seems ChatGPT consider only the JSX section being part of the render function, but App2 is the render function, and is re-executed in its interety every time there’s a re-render, so recreating each time also fn.
When I pointed this out with ChatGPT, it apologized (of course), and changed its version.

So I’m asking this here: Is any difference in these two components?

2

Answers


  1. Never trust a robot to do a programmer’s job. :snort:

    The lambda is created anew on each render in both cases. To avoid the lambda being re-created it would need to be wrapped in something like useMemo or moved outside of the component.

    i.e. they are the same

    Login or Signup to reply.
  2. If you want to only declare your function once, you must put it outside the component

    const fn = () => null;
    
    function App () {    
      return <button onClick={fn}>Click me</button>
    }
    

    If you want to cache function definitions between re-renders, make sure to wrap it in a useCallback hook

    function App () {    
      const fn = useCallback(() => null, []);
    
      return <button onClick={fn}>Click me</button>
    }
    

    Reference: https://react.dev/reference/react/useCallback

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search