← Back to Chapters

Avoiding Unnecessary Re-renders

? Avoiding Unnecessary Re-renders

? Quick Overview

Unnecessary re-renders in React happen when components update without any real change in output. Optimizing these renders improves performance, responsiveness, and user experience.

⚛️ Introduction

React re-renders components whenever state or props change. While this is by design, too many unnecessary re-renders can degrade performance, especially in large applications.

In this section, we’ll explore how to identify and avoid unwanted renders for smoother, faster React apps.

? Why Re-renders Happen

  • A component’s state changes.
  • A component’s props change (even if values are same but reference is new).
  • A parent re-renders and triggers re-renders down the tree.
  • A context value updates and affects all consumers.

? Identifying Unnecessary Re-renders

  • React Developer Tools → Highlight updates
  • React Profiler
  • Console logging inside components
? View Code Example
// Logs each time the component renders
function Item({ name }) {
console.log(`Rendered: ${name}`);
return <li>{name}</li>;
}

⚙️ Techniques to Avoid Unnecessary Re-renders

1️⃣ React.memo()

? View Code Example
// Prevents re-render unless props change
const Product = React.memo(function Product({ name, price }) {
console.log("Product rendered");
return <p>{name}: ${price}</p>;
});

2️⃣ useCallback()

? View Code Example
// Memoizes function reference
const handleClick = useCallback(() => {
console.log("Clicked");
}, []);

3️⃣ useMemo()

? View Code Example
// Memoizes expensive computation
const filteredData = useMemo(() => data.filter(item => item.active), [data]);

4️⃣ Avoid Inline Objects

? View Code Example
// Inline object causes re-render
<Child options={{ theme: "dark" }} />

// Memoized object prevents re-render
const options = useMemo(() => ({ theme: "dark" }), []);
<Child options={options} />

? Parent–Child Optimization Example

? View Code Example
// Parent component with memoized callback
function Parent() {
const [count, setCount] = useState(0);
const increment = useCallback(() => setCount(p => p + 1), []);
return (
<div>
<button onClick={increment}>Increment</button>
<Child />
</div>
);
}

// Child wrapped with React.memo
const Child = React.memo(() => {
console.log("Child rendered");
return <p>No unnecessary re-render</p>;
});

? Interactive Concept

Click the button below to update the Parent's state. Watch how the Memoized Child stays static (saved processing) while the Regular Child re-renders unnecessarily.

Parent Component
State Count: 0
Regular Child
Re-renders: 0
Renders on every parent update.
React.memo() Child
Re-renders: 1
Only renders if props change.

? Tips & Best Practices

  • Profile before optimizing.
  • Keep dependency arrays accurate.
  • Use memoization selectively.

? Try It Yourself

  1. Add console logs to components.
  2. Apply React.memo and observe behavior.
  3. Use DevTools highlight updates.