useCallback Basics

Syntax

const handleClick = useCallback(() => {
  doSomething(id);
}, [id]);

Every render creates new function objects. useCallback returns the same function until a dependency changes. useCallback(fn, deps) equals useMemo(() => fn, deps).

With React.memo

Example

Child is wrapped in React.memo, so it skips re-rendering when its props are the same. Clicking "Increment parent" logs the child render only for the version that gets a new function each time.

import { useState, useCallback, memo } from 'react';

const Child = memo(function Child({ label, onClick }) {
  console.log('render ' + label);
  return <button onClick={onClick}>{label}</button>;
});

export default function App() {
  const [count, setCount] = useState(0);
  const stable = useCallback(() => alert('stable click'), []);
  const unstable = () => alert('unstable click');
  return (
    <div>
      <p>Parent count: {count} <button onClick={() => setCount(count + 1)}>Increment parent</button></p>
      <Child label="with useCallback" onClick={stable} />
      <Child label="without useCallback" onClick={unstable} />
    </div>
  );
}

Result