Skip to main content

Understanding Re-renders in React: What Causes a Component to Re-render #121

📖 Introduction

Welcome to a new chapter focused on a critical aspect of building high-quality React applications: performance and optimization. We'll begin by exploring a fundamental concept that is at the heart of React's performance model: re-renders. Understanding what causes a component to re-render is the first step to writing more performant code.


📚 Prerequisites

Before we begin, please ensure you have a solid grasp of the following concepts:

  • React components, props, and state.
  • The useState hook.
  • The Context API.

🎯 Article Outline: What You'll Master

In this article, you will learn:

  • What a Re-render Is: Understanding the concept of re-rendering in React.
  • The Four Main Causes of Re-renders: A deep dive into the four main reasons why a component will re-render.
  • Practical Examples: Seeing each of these causes in action with simple, clear examples.

🧠 Section 1: The Core Concepts of Re-renders

In React, a re-render is the process of a component being rendered again, typically in response to a change in its data. This is a core part of how React works, and it's what allows your UI to stay in sync with your application's state.

While re-renders are necessary, unnecessary re-renders can lead to performance issues, especially in large and complex applications. By understanding what causes a component to re-render, you can learn to identify and eliminate these unnecessary re-renders.

There are four main reasons why a component will re-render:

  1. State Changes: When a component's state changes.
  2. Parent Component Re-renders: When a parent component re-renders.
  3. Context Changes: When a context that the component is consuming changes.
  4. Hook Changes: When a hook that the component is using changes its state.

💻 Section 2: Deep Dive - The Four Causes of Re-renders

Let's explore each of these causes in more detail.

2.1 - State Changes

This is the most common cause of a re-render. When you update a component's state using the useState or useReducer hook, React will re-render that component and all of its children.

import React, { useState } from 'react';

function Counter() {
const [count, setCount] = useState(0);

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

In this example, every time the button is clicked, the count state is updated, and the Counter component re-renders.

2.2 - Parent Component Re-renders

When a parent component re-renders, all of its child components will re-render by default, even if the children's props have not changed.

import React, { useState } from 'react';

function Child() {
console.log('Child re-rendered');
return <p>I am a child component.</p>;
}

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

return (
<div>
<p>Parent count: {count}</p>
<button onClick={() => setCount(count + 1)}>Re-render Parent</button>
<Child />
</div>
);
}

In this example, every time the button is clicked, the Parent component re-renders, which in turn causes the Child component to re-render.

2.3 - Context Changes

When the value of a React Context changes, all components that consume that context will re-render.

import React, { useState, useContext, createContext } from 'react';

const ThemeContext = createContext();

function ThemedButton() {
const theme = useContext(ThemeContext);
console.log('ThemedButton re-rendered');
return <button>The theme is {theme}</button>;
}

function App() {
const [theme, setTheme] = useState('light');

return (
<ThemeContext.Provider value={theme}>
<ThemedButton />
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Toggle Theme
</button>
</ThemeContext.Provider>
);
}

In this example, every time the "Toggle Theme" button is clicked, the theme value in the ThemeContext.Provider changes, which causes the ThemedButton component to re-render.

2.4 - Hook Changes

If a component uses a custom hook that has its own state, any update to that state will cause the component to re-render.

import React, { useState } from 'react';

function useToggle(initialValue = false) {
const [value, setValue] = useState(initialValue);
const toggle = () => setValue(!value);
return [value, toggle];
}

function MyComponent() {
const [isOpen, toggleOpen] = useToggle(false);
console.log('MyComponent re-rendered');

return (
<div>
<button onClick={toggleOpen}>{isOpen ? 'Close' : 'Open'}</button>
{isOpen && <p>Content</p>}
</div>
);
}

In this example, the useToggle hook manages the isOpen state. When the button is clicked, the toggleOpen function is called, which updates the state within the hook, causing MyComponent to re-render.


💡 Conclusion & Key Takeaways

In this article, we've learned about the four main causes of re-renders in React. Understanding these concepts is the first step to identifying and optimizing performance issues in your applications.

Let's summarize the key takeaways:

  • A re-render is the process of a component being rendered again.
  • The four main causes of re-renders are state changes, parent component re-renders, context changes, and hook changes.
  • Unnecessary re-renders can lead to performance issues.

Challenge Yourself: To solidify your understanding, try to create a simple application that demonstrates all four causes of re-renders. Use console.log to track when each component re-renders.


➡️ Next Steps

You now have a solid understanding of what causes a component to re-render. In the next article, "React.memo for Component Memoization (Part 1)", we will explore our first tool for optimizing performance: React.memo.

Thank you for your dedication. Stay curious, and happy coding!


glossary

  • Re-render: The process of a component being rendered again in response to a change in its data.
  • Memoization: An optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again.

Further Reading