JAVASCRIPT

Optimize Event Handlers with useCallback to Prevent Unnecessary Rerenders

Understand how to use the `useCallback` hook in React to memoize function definitions, preventing child components from re-rendering due to new function instances.

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

const ChildComponent = React.memo(({ onClick }) => {
  console.log('ChildComponent rendered');
  return <button onClick={onClick}>Click Me (Child)</button>;
});

function ParentComponent() {
  const [count, setCount] = useState(0);

  // Without useCallback, this function would be recreated on every ParentComponent render
  // With useCallback, it's memoized as long as count doesn't change
  const handleClick = useCallback(() => {
    setCount(prevCount => prevCount + 1);
    console.log('Button clicked!');
  }, []); // Dependency array: empty because handleClick doesn't depend on `count` directly

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment Parent Count</button>
      <ChildComponent onClick={handleClick} />
    </div>
  );
}

export default ParentComponent;
How it works: The `ChildComponent` is wrapped with `React.memo` to prevent re-renders if its props haven't changed. In `ParentComponent`, `handleClick` is wrapped with `useCallback`. This ensures that the `handleClick` function instance remains the same across re-renders of `ParentComponent`, as long as its dependencies (none in this case, as `setCount` is stable) don't change. This prevents `ChildComponent` from re-rendering when `ParentComponent` updates other state (like `count`), because the `onClick` prop remains referentially equal.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs