Skip to content

useCallback to prevent re-created function

Published: at 01:30 PM

What is useCallback?

When to use useCallback:

How it works:

  1. You call useCallback with two arguments:

    • The callback function itself: This is the function you want to memoize.
    • An array of dependencies: This array specifies the values that the callback function depends on. If any of these values change, the memoized callback function will be recreated. If the dependencies array is empty ([]), the callback function will only be created once.
  2. useCallback returns a memoized version of the callback function. This function will have the same identity as long as its dependencies haven’t changed. This means that if you pass the memoized function to a child component as a prop or use it as an event handler, React will be able to compare it to the previous version and determine if it has actually changed.

Example:

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

function ParentComponent() {
  const [count, setCount] = useState(0);
  const handleClick = useCallback(() => {
    setCount(count + 1);
  }, [count]); // Only recreate handleClick if count changes

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

function ChildComponent({ handleClick }) {
  console.log("Child component rendered");
  // ...
}

In this example, handleClick is memoized using useCallback with count as a dependency. This ensures that ChildComponent only re-renders when count actually changes, even if ParentComponent itself re-renders due to other changes.

Additional benefits:

Remember:

You can use useCallback() function to avoid re-created function

import React, { useState, useCallback, useEffect } from "react";
import "./styles.css";

// Register functions
const functionsCounter = new Set();

export default function App() {
  const [counter, setCounter] = useState(0);
  const [otherCounter, setOtherCounter] = useState(0);

  // const increment = () => {
  //   setCounter(counter + 1);
  // }
  // const decrement = () => {
  //   setCounter(counter - 1);
  // }
  // const incrementOtherCounter = () => {
  //   setOtherCounter(otherCounter + 1)
  // }

  const increment = useCallback(() => {
    setCounter(counter + 1);
  }, [counter]);

  const decrement = useCallback(() => {
    setCounter(counter - 1);
  }, [counter]);

  const incrementOtherCounter = useCallback(() => {
    setOtherCounter(otherCounter + 1);
  }, [otherCounter]);

  useEffect(() => {
    functionsCounter.add(increment);
    functionsCounter.add(decrement);
    functionsCounter.add(incrementOtherCounter);
  }, [increment, decrement, incrementOtherCounter]);

  return (
    <div className="App">
      <h1>
        <code>useCallback()</code>
      </h1>
      <h3>{`function call: ${functionsCounter.size}`}</h3>
      <button onClick={decrement}>Decrement</button>
      {` ${counter} `}
      <button onClick={increment}>Increment</button>
    </div>
  );
}

🚀 try codesandbox

Thank you for reading this article, I hope you find it useful. Happy coding! 🔥