Blog/NotesConcept

Mastering React Rendering: How memo and useCallback Eliminate Unnecessary Re-renders

React's rendering is powerful but can become a performance bottleneck in larger apps. Every state change triggers re-renders across your component tree—sometimes unnecessarily. Enter React.memo and useCallback: your optimization superheroes that prevent wasted renders and keep your app snappy.

Intermediate

Prateek Labroo

Last Updated Jun 9, 2026


Mastering React Rendering: How memo and useCallback Eliminate Unnecessary Re-renders

The Problem: Uncontrolled Re-rendering Cascade

Imagine a simple Todo app. When you type in the input field, everything re-renders—even components that haven't changed. Here's why:

Without optimization (problematic version):

Console output when typing:

Parent renders TodoInput re-rendered! TodoList re-rendered! // Even worse with 100+ todos

Why this happens:

  1. handleInputChange is a new function reference every render

  2. React.memo does shallow prop comparison

  3. New function = "props changed" = re-render everything

The Solution: memo + useCallback Magic

Here's the optimized version that stops unnecessary renders:

1. Parent Component (Fully Optimized)

2. Memoized Child Components

// TodoList.jsx - ✅ memoized
import { memo } from "react";

export default memo(function TodoList({
  todos,
  handleEdit,
  handleDelete,
  handleComplete,
  handleEditedTodo,
}) {
  console.log("TodoList"); // Only logs when todos array changes
  return (
    <div className="flex flex-col gap-4 mt-3 overflow-auto flex-grow">
      {todos.map((todo) => (
        <div key={todo.id} className="flex justify-start p-2 items-center">
          {todo.edit ? (
            <input
              type="text"
              value={todo.text}
              className="border border-gray-300 rounded-lg p-2 flex-grow mr-2"
              onChange={(e) => handleEditedTodo(e, todo.id)}
            />
          ) : (
            <span
              className={`self-start border border-gray-300 rounded-lg p-2 flex-grow mr-3 text-wrap transition-all ease-in-out ${
                todo.completed
                  ? "line-through text-red-500"
                  : "text-teal-600 underline"
              }`}
            >
              {todo.text}
            </span>
          )}
          <div className="flex gap-2">
            <button
              className="text-blue-500 hover:text-blue-700 cursor-pointer"
              onClick={() => handleEdit(todo.id)}
            >
              {todo.edit ? "Save" : "Edit"}
            </button>
            <button
              className="text-red-500 hover:text-red-700 cursor-pointer"
              onClick={() => handleDelete(todo.id)}
            >
              Delete
            </button>
            <button
              className="text-green-500 hover:text-green-700 cursor-pointer"
              onClick={() => handleComplete(todo.id)}
            >
              Complete
            </button>
          </div>
        </div>
      ))}
    </div>
  );
});

Visual Proof: Before vs After

Scenario Without Optimization With memo + useCallback
Typing in input Parent + Both children re-render Only TodoInput
Adding todo All re-render Parent + TodoList
Editing todo #5 All re-render Only TodoList
100 todos + typing 300ms lag <10ms

Key Takeaways & Pro Tips

🎯 useCallback Rules

✅ Memoize functions passed as props
✅ Empty deps [] for functions without state deps
✅ Include changing state in deps array
❌ Don't overdo it - small apps might not need it 

🎯 React.memo Rules

✅ Use for pure components with stable props 
✅ Great for lists/item components 
✅ Won't help if props keep changing

🚀 Bonus Optimizations

// 1. useCallback for event handlers const handleClick = useCallback((id) => {}, [id]);
// 2. Memoize objects/arrays passed as props const config = useMemo(() => ({ limit: 10, sort: 'asc' }), []); 
// 3. Custom comparison for memo const MyComponent = memo(Component, (prev, next) => { return prev.count === next.count; // Deep compare if needed });

Performance Impact in Real Numbers

Todo App with 500 items: 
✅ Improvement: 20x faster!
❌ Without optimization: 245ms per keystroke 
✅ With memo + useCallback: 12ms per keystroke 

Bottom line: For lists, forms, and interactive UIs, memo + useCallback = must-have optimization. Your users will notice the difference!

Love this Blog? Share it Now!

Help others discover this resource

About the Author

Prateek Labroo


Learn Next

Featured

100+ Top React JS Interview Questions And Answers

20 Most Asked Custom Hooks in React for InterviewsTop 10 React Performance Optimization Techniques25 Top JavaScript Interview Questions for BeginnersHow to create custom useInfiniteScroll Hook in ReactImplement useThrottle Custom Hook In React

Comments

Be the first to share your thoughts!

Guest User

Please login to comment

0 characters


No comments yet.

Start the conversation!

About the Author

Prateek Labroo

Share your expertise

Publish a blog or quick notes on topics you know well — your write-up could be the answer someone needs before their next frontend interview.

Build your portfolio

Help the community

Sharpen your skills

Earn goodies

Other Related Blogs

Top 10 React Performance Optimization Techniques [React Interview]

Anuj Sharma

Last Updated Jun 19, 2026

Find the top React Performance Optimization Techniques specific to React applications that help to make your react app faster and more responsive for the users along with some bonus techniques.

useDeferredValue vs useTransition: Difference and Trade-Off

Anuj Sharma

Last Updated Jun 20, 2026

Explore useDeferredValue vs useTransition in React with examples. Learn key differences between useDeferredValue and useTransition, use cases and when to choose one over the other in React applications.

How to create custom useInfiniteScroll Hook in React

Anuj Sharma

Last Updated Jun 20, 2026

Learn how to implement useInfiniteScroll hook in react to handle long list of items efficiently using intersection observer internally.

useRef vs useState in React: Difference & Trade-off

Anuj Sharma

Last Updated Jun 19, 2026

Explore useRef vs useState in React with examples. Learn the key differences between useRef and useState, use cases, advantages, and disadvantages, and when to choose one over the other in React applications.

useRef vs createRef in React: Difference and Trade Off

Anuj Sharma

Last Updated Jun 19, 2026

Explore useRef vs createRef in React with examples. Learn the key differences between useRef and createRef, use cases and when to choose one over the other in React applications

useMemo vs useCallback in React: Difference and Trade Off

Anuj Sharma

Last Updated Jun 19, 2026

Explore useMemo vs useCallback in React with examples. Learn the key differences between useMemo and useCallback, use cases, and when to choose one over the other in React applications.

useState vs useReducer in React: Understand the Difference & Trade-Off

Anuj Sharma

Last Updated Jun 19, 2026

Explore useState vs useReducer in React with examples. Learn key differences, use cases, advantages, disadvantages, and when to choose one over the other in React applications and interviews.

React.memo vs useMemo in React: Difference & Trade Off

Anuj Sharma

Last Updated Jun 19, 2026

Explore React.memo vs useMemo in React with examples. Learn key differences between React.memo and useMemo, use cases and when to choose one over the other in React applications.

Stay Updated

Subscribe to FrontendGeek Hub for frontend interview preparation, interview experiences, curated resources and roadmaps.

FrontendGeek
FrontendGeek

All in One Preparation Hub to Ace Frontend Interviews. Master JavaScript, React, System Design, and more with curated resources.

Consider Supporting this Free Platform

Buy Me a Coffee

Product

HomeFrontend InterviewFrontend JobsQuestionsNewInterview ExperienceBlogsToolsLeaderboardFrontendGeek Chrome extensionGet the extension on the Chrome Web Store

© 2026 FrontendGeek. All rights reserved