'Which one is more efficient on saving rendering? (React)

I am wondering two cases, which is better for writing?

case 1

import * as React from 'react';


const TestComponent:React.FC = () => {
    const [count, setCount] = React.useState<number>(0)

    const increment = () => {
        setCount(count + 1)
    }

    console.log("rendering...")

    return <div>
        <div><span>{count}</span></div>
        <button onClick={increment}>click</button>
        </div>
}

export default TestComponent

case 2

import * as React from 'react';


const TestComponent:React.FC = () => {
    const [count, setCount] = React.useState<number>(0)

    const increment = () => {
        setCount(count + 1)
    }

    console.log("rendering...")

    return <div>
        <div><span>{count}</span></div>
        <button onClick={_ => increment()}>click</button>
        </div>
}

export default TestComponent

For case 2, I am the following double. Is the arrow function recreated on each render phase?

 onClick={_ => increment()}


Solution 1:[1]

Yes, your onClick is recreated on every render.

However the same applies to the increment function:

const increment = () => {
  setCount(count + 1)
}

since the whole body of your component runs every time. You can see this by watching "rendering..." logged in each counter change.

So in the 1st example you have one function reacreating in every render while in the 2nd you recreate 2 functions in each render.

That said you should go with the 1st one. If you want to avoid recreation you should use useCallback to memoize it. For example if you pass that onClick callback as a prop to an 'expensive' component, you need to pass the same reference each time to avoid expensive updates.

Solution 2:[2]

In the first case you are re-creating increment on every render.

In the second case you are re-creating both increment and the arrow function, so from this point of view you are creating one more function in the second case.

The difference in performance is negligible.

There is a third way of writing this:

<button onClick={_ => setCount(count+1)}>click</button>

Again, you will create an arrow function each time, but you won't pollute the component with the increment functions.

This being said, I think all approaches are valid. Maybe the second one is superfluous as you can just pass the function as param.

My reasoning when deciding if you declare a function that alters a state and use that one is related to how much am I gonna use it. If I'm just updating the state without any further business logic then you can just update the state.

If updating the state implies some more business logic then declare a new function and use it.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 fgkolf
Solution 2 marc_s