Does useCallback hook create a function everytime a component renders in React.js?

During the job interview, I was asked how to optimize a component in React.

So I answered with an example of using useCallback and useMemo hooks.

Because whenever a components re-renders, functions and variables declared inside of the component are newly created which results in those newly created values occupying memory space.

However, with a help of those two hooks, it is possible to save memory because using useCallback and useMemo prevents creating the function and variable again and again by saving and reusing the previous result, as long as a state inside the dependency array is not changed during the component re-rendering.

So far, this was my answer. But the interviewer said useCallback does not prevent creating a function. Even if useCallback is used, a function is still created.

I do not get this part. How is the function created again inside the useCallback hook?

Is there something I’m missing about useCallback and useMemo?

Answer

Here I made an example so you can see useCallback in action:

In the example bellow: useCallback will prevent newly changeWithUseCallback re-create every new render, result that Child1 never gets re-render because it’s props (changeWithUseCallback) never re-created.

Otherwise, in the Child2 component, its prop (changeWithoutUseCallback) is always re-created during renders, so the component itself will re-render.

Please note that React.memo will skip rendering the component if its props have not changed

So I would say that you are right about useCallback that it will keep the function/variable reference during renders, or prevent creating new function/variable during renders.

function App() {
  const [value, setValue] = React.useState(0);
  const changeWithUseCallback = React.useCallback(() => {
    console.log("onChangeChild");
  }, []);
  const changeWithoutUseCallback = () => {
    console.log("onChangeChild");
  };
  return (
    <div className="App">
      <button type="button" onClick={() => setValue(value + 1)}>
        Change value
      </button>
      <h1>{value}</h1>
      <Child1 onChange={changeWithUseCallback} />
      <Child2 onChange={changeWithoutUseCallback} />
    </div>
  );
}

const Child1 = React.memo(({ onChange }) => {
  console.log("Child1 render!!!");
  return null;
});

const Child2 = React.memo(({ onChange }) => {
  console.log("Child2 render!!!");
  return null;
});

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>