R

React Handbook

Clean • Professional

React useCallback Hook

2 minute

React useCallback Hook

In React, functional components re-render whenever their state or props change. This means that functions defined inside components are re-created on every render, which can lead to unnecessary re-renders of child components if these functions are passed as props.

The useCallback hook solves this by caching a function so that its reference remains stable between renders unless its dependencies change. This is a key tool for performance optimization in React apps.

What is useCallback?

useCallback is a React hook that returns a memoized version of a function, preventing its re-creation on every render.

Syntax:

const memoizedFunction = useCallback(() => {
  // function logic
}, [dependencies]);

  • memoizedFunction → The cached function reference
  • [dependencies] → Array of variables; the function updates only if these change

Why Use useCallback?

  • Prevent unnecessary re-renders: When passing functions as props to child components wrapped in React.memo().
  • Maintain referential equality: The function keeps the same reference across renders.
  • Optimize large applications: Especially when functions trigger expensive child re-renders.

Example: 

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

const Button = React.memo(({ handleClick, label }) => {
  console.log(`Rendering Button: ${label}`);
  return <button onClick={handleClick}>{label}</button>;
});

function App() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState("");

  // Memoized function
  const increment = useCallback(() => {
    setCount(c => c + 1);
  }, []); // Function remains the same until dependencies change

  return (
    <div>
      <h1>Count: {count}</h1>
      <Button handleClick={increment} label="Increment" />
      <inputtype="text"
        value={text}
        onChange={e => setText(e.target.value)}
        placeholder="Type something..."
      />
    </div>
  );
}

export default App;
  • The increment function is memoized, so Button does not re-render unnecessarily when text changes.
  • Without useCallback, increment would be re-created on every render, causing Button to re-render even if its props haven’t changed.

useCallback with Dependencies

When a memoized function depends on other variables, include them in the dependency array:

const incrementBy = useCallback(() => {
  setCount(count + 1);
}, [count]); // Updates function if 'count' changes
  • The function is recreated only when count changes.
  • This ensures correctness without triggering unnecessary renders.

Article 0 of 0