React: Optimization callbacks with or without useCallback

529 Views Asked by At

TL;DR

Some blogs say that you don't need to use the useCallback hook every time you pass a callback to child component, and sometimes it is better to create a new function every time. Because the cost of useCallback sometimes higher than the actual performance issue. While React warns that it may lead to performance issues and we need to try to avoid it.
Who is right and what is the way to balance between these two opposing claims?

The full question

I've been reading a lot of blogs and tutorials about react hooks recently, specially about useCallback and useMemo.

Before React 16 (and all its hooks) when I use Class Components, I've always used "constructor binding" for my callbacks, because arrow function or "Bind in render" like those:

render() {
  return <button onClick={this.handleClick.bind(this)}>Click Me</button>;
}

render() {
  return <button onClick={() => this.handleClick()}>Click Me</button>;
}

Were considered as "bad practice". From React Docs:

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

Using an arrow function in render creates a new function each time the component renders, which may break optimizations based on strict identity comparison.

So, my rule of thumb was not to pass new functions to props.

In React 16 the useCallback hook tries to helps us to do exactly that thing. But I see a lot of blogs like that or that claim that you don't need to use the useCallback hook every time because the cost of useCallback sometimes higher than the actual issue, and using arrow functions that create a new function on every render is fine.

Both opposing claims made me think that the best option should be something like (if the dependencies array is empty):

function handleCallback() { ... } // Or arrow function...

function Foo(props) {
   return <button onClick={handleCallback}>Click Me</button>
}

Because this way doesn't use the "expensive" useCallback and doesn't generating a new function every time. But, actually, this code is not looking so good when you have several callbacks.

So, what is the right balance between these two opposing claims? If creating a new function every time sometimes better than using useCallback, why React has a warning in their docs about it?

(Same question about the "double curly braces" rule of thumb and useMemo/useRef hooks)

0

There are 0 best solutions below