2

Consider example:

const Child = () => {
  console.log("I did re-render!");
  return null;
};

const App = () => {
  const [_, setValue] = useState();
  const fn = useCallback(() => {
    // do something
  }, []);

  return (
    <div>
      <button onClick={() => setValue(Math.random)}>click</button>
      <Child fn={fn} />
    </div>
  );
};

With every state change in App (click the button), the Child component re-renders, even if the passed prop fn is wrapped with useCallback. However, if I wrap Child with React.memo, it starts to work correctly - it does not re-render when parent re-renders.

My question: What's the point of using useCallbacks without React.memo?? Should I always use React.memo if I dont want the component to always re-render if its parent re-renders?

Should useCallbacks always be used with React.memo? Because it seems like they are senseless and useless without React.memo.

Playground: https://codesandbox.io/s/peaceful-khorana-nrojpb?file=/src/App.js

underfrankenwood
  • 285
  • 1
  • 10
  • Did https://reactjs.org/docs/hooks-reference.html#usecallback not explain what it's for well enough? You don't explicitly need `React.memo` when you use `useCallback`, it already yields a memoized function. – Mike 'Pomax' Kamermans Mar 09 '22 at 15:53
  • @Mike'Pomax'Kamermans if it yields a memoized function already, why does the child component re-render? The shallow comparison doesnt occur at all? Unless you use `React.memo`? – underfrankenwood Mar 09 '22 at 15:55
  • @Mike'Pomax'Kamermans The docs you linked say "*[It] is is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. shouldComponentUpdate).*" So indeed, `useCallback` is not useful if the `` is not optimised by `React.memo` or `useMemo`. – Bergi Mar 09 '22 at 15:56
  • 1
    Memoized functions don't prevent rerenders in any way, they just prevent "rerunning the _function_ to get its output data for rendering", only updating their value when a dependency of the function has changed. But in this case, the callback has an empty dependency list, completely negating the point of memoization, its dependencies will never change and it's basically a `const` with more code =) – Mike 'Pomax' Kamermans Mar 09 '22 at 15:58
  • So in the fact, `useCallback` is only useful when we want to avoid an endless loop in e.g. `useEffect` when passing the wrapped function as a dependency. In sake of avoiding children re-render, its completely pointless to use it without `React.memo`. Thanks @Bergi – underfrankenwood Mar 09 '22 at 16:01
  • Related, if not duplicate: [React, when to use useCallback?](https://stackoverflow.com/q/71265042/1048572) – Bergi Mar 09 '22 at 16:02

0 Answers0