/blog/react-performance-a-deep-dive-into-usememo-and-usecallback/ - zsh
user@portfolio ~ $

cat react-performance-a-deep-dive-into-usememo-and-usecallback.md

React Performance: A Deep Dive into useMemo and useCallback

Author: Aslany Rahim Published: December 07, 2025
React is fast, but unnecessary re-renders can kill your app's performance. Learn exactly when (and when NOT) to use useMemo and useCallback to optimize your components.

React's core mechanic is simple: When state changes, the component re-renders. Usually, this is fast enough. But in complex applications, you might find your UI lagging when typing in an input field or switching tabs.

This usually happens because expensive calculations are running on every keystroke, or child components are re-rendering when they don't need to.

React provides two hooks to solve this: useMemo and useCallback.

Referential Equality

To understand these hooks, you must understand how JavaScript compares objects.

const a = { id: 1 };
const b = { id: 1 };
console.log(a === b); // FALSE

Even though they look the same, they are different places in memory. In React, if you define a function inside a component, that function is recreated every single time the component renders.

If you pass that function to a child component, the child thinks "Oh, I got a new prop!" and re-renders too, even if nothing actually changed.

1. useCallback

useCallback caches a function definition between renders.

The Problem:

const Parent = () => {
  const [count, setCount] = useState(0);

  // This function is recreated on every click!
  const handleClick = () => {
    console.log('Clicked');
  };

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

Even though ChildComponent shouldn't care about count, it re-renders because handleClick is technically a "new" function.

The Solution:

const handleClick = useCallback(() => {
  console.log('Clicked');
}, []); // No dependencies, never recreated

2. useMemo

useMemo caches the result of a calculation.

The Problem:

const Component = ({ data }) => {
  // This runs on every render. If data is huge, the app freezes.
  const sortedData = data.sort((a, b) => a.value - b.value);

  return <List items={sortedData} />;
}

The Solution:

const sortedData = useMemo(() => {
  return data.sort((a, b) => a.value - b.value);
}, [data]); // Only run if 'data' changes

The Trap: Premature Optimization

You might think, "I should wrap everything in useMemo!" Don't.

These hooks come with a cost. React has to allocate memory to store the dependencies and compare them. For simple calculations (like a + b) or simple button clicks, standard JavaScript is faster than the overhead of useMemo.

Rules of Thumb

  1. Use useMemo for heavy data processing (sorting thousands of rows, complex filtering).
  2. Use useCallback when passing functions to children that are wrapped in React.memo.
  3. Use useCallback when a function is in the dependency array of a useEffect.
44 views
0 comments

Comments (0)

Leave a Comment

No comments yet. Be the first to comment!

Related Posts

Building Offline-First React Native Apps

Mobile users lose connectivity constantly (elevators, subways, flights). Learn how to cache data using Async Storage and NetInfo so your …

December 04, 2025

Why I Switched to TypeScript for React (And You Should Too)

Are you tired of undefined is not a function errors crashing your production app? It's time to graduate from JavaScript …

December 01, 2025

React Native Navigation: Stack vs. Tab vs. Drawer

Unlike the web, mobile apps don't have a URL bar. We explore how to structure your mobile app using React …

November 28, 2025

user@portfolio ~ $ _