Understanding React Rendering: Part 1 – When Does React Re-render UI elements?

One of the key features of React is its ability to update the user interface efficiently by re-rendering components when there are changes to the state or props. However, this re-rendering can be expensive, especially for complex applications with large amounts of data. This article will explore how React triggers a re-render.

Revise the life cycle of a component in React

The life cycle of a React component represents the different phases of the lifetime of a component.

Phases of the life cycle of React Components
Phases of the life cycle of React Components

When does React render UI elements?

React is listening to any changes to states and props. Then, it will render or re-render UI elements if at least one change has been made to any of the UI elements. Suppose your component makes up more than one UI element. In that case, the rendering is potentially expensive because React will recompute everything although it uses shallow comparison to detect which elements have been updated in their states or props.

React recognised those changes because we use hooks such as useState, useEffect, and so on.

Let’s work out the following example:

import './App.css';
import SumComp from "./shared/SumComp";

function App() {
  return (
    <div className="App">
      <SumComp/>
    </div>
  );
}

export default App;

The SumComp component is defined below.

import React, {useState, useMemo} from 'react';

function SumComp() {
    console.log("Rendering SumComp component...");
    const COLOURS = ['aqua', 'blue', 'fuchsia', 'gray', 'green',
        'lime', 'maroon', 'navy', 'olive', 'orange', 'purple', 'red',
        'silver', 'teal', 'yellow'];
    const cId = randomColor(COLOURS.length);
    const [colorName, setColorName] = useState(COLOURS[cId]);
    const [txt, setTxt] = useState("Some text");
    const [a, setA] = useState(0);
    const [b, setB] = useState(0);
    // const sum = useMemo(() => {
    //     console.log("Computing sum...");
    //     return a + b;
    // }, [a, b]);
    const sum = expensiveComputing(a, b);
    return (
        <div>
            <p>Text: <span style={{"color": colorName}}>{txt}</span></p>
            <p>a: {a}</p>
            <p>b: {b}</p>
            <p>sum: {sum}</p>
            <button onClick={() => {
                const text = Math.random().toString(36).slice(2, 7);
                setTxt(text);
                const colorIndex = randomColor(COLOURS.length);
                const colorName = COLOURS[colorIndex];
                setColorName(colorName);
            }}>Click here to change text and color</button>
            <button onClick={() => setA(a + 1)}>Increment a</button>
            <button onClick={() => setB(b + 1)}>Increment b</button>
        </div>
    );
}

function randomColor(max) {
    console.log("Calling random color index...")
    return Math.floor(Math.random()*max);
}
function expensiveComputing(x, y) {
    console.log("Calling expensive computing...");
    return x + y;
}

export default SumComp;

Starting the application, the page looks like below.

Screenshot of the example
Screenshot of the example when it is fully loaded at first

In the source code published here in the rendering branch, we define a component called SumComp which has a paragraph to capture a random text, a paragraph to hold the value of the variable a and another paragraph to hold the value of the variable b.  Also, we need another paragraph to hold the sum of the value a and b.

Analysis

After the page loading

How React renders UI elements - Analysis of the example - loading
How React renders UI elements – Analysis of the example – loading

As shown in the screenshot above, React has called the function to define SumComp component (Rendering SumComp component) where the local function generates a colour code (Calling random color index) and the function computes a sum expensively (Calling expensive computing).

Click on the Click here to change text and color button (called C1)

How React renders UI elements - Analysis of the example - Click change colour and text
How React renders UI elements – Analysis of the example – Click to change colour and text

When clicking on the C1, React detects the changes to the colour name and text which are randomly chosen. It calls all functions defined in the component although the variable a and b do not change. The expensive computing function is also called even if a and b are still 0. Imagine that the expensive computing function takes longer to finish.

Click on the Increment a or Increment b button (called C2)

How React renders UI elements - Analysis of the example - Click to increment a or b variable
How React renders UI elements – Analysis of the example – Click to increment a or b variable

Similarly, clicking on any of these two buttons also hits all functions and logic defined in the SumComp component. It shouldn’t behave that way. Certainly, React offers us some approaches to avoid such a problem, for instance, using useMemo or useCallback hook or Lazy loading technique. We will learn about these techniques in the next posts.

Take away

In this post, we have learned how and when React renders and re-renders components based on the changes to the states or props in the components. When a state or prop is updated, React renders everything defined in components without taking care of whether the other states or props have been changed or not. That’s the reason we should pay attention to when building complex components where they have to cooperate with different states and data coming from different resources. To grasp more about optimizing rendering components, we have a series of improving React rendering for you. For the sake of finality, please take a look at our source code at https://github.com/ITersDesktop/react-caching.

References

[1] React, https://react.dev/, accessed Jan 2nd 2024

[2] Understanding React Re-rendering: An Overview of Shallow Comparison and Optimization with Examples, https://www.linkedin.com/pulse/understanding-react-re-rendering-overview-shallow-examples-pandey/, accessed Jan 2nd 2024

[3] Optimizing Web Apps in React, https://www.turing.com/kb/optimize-web-apps-in-react, accessed Jan 2nd 2024

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.