DEV Community

Ogunlari Ololade
Ogunlari Ololade

Posted on

React Mental Models 2

A Walk Through setState continuation:

How React Actually Renders: Understanding the Render Lifecycle

When building with React, it's easy to focus on writing components and managing state without fully understanding what happens under the hood. However, grasping how React transforms a state update into real browser pixels is essential for writing performant applications and debugging edge cases.
Let's break down the core mechanics of React rendering, clear up common misconceptions, and establish the foundational mental models every React developer needs.

The Lifecycle of a State Change

import React, { useState } from 'react';

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

    return (
        <>
            <h1>{count}</h1>
            <button onClick={() => setCount(count + 1)}>
                Increment
            </button>
        </>
    );
}
Enter fullscreen mode Exit fullscreen mode

Notice that nowhere in this code do we instruct React to find an h1 element and update its content. We simply describe what the UI should represent for a given state.
React assumes full responsibility for determining how to transition the browser from one UI state to another. This separation of concerns—describing what the interface should look like rather than how to update it—is one of the primary reasons React applications scale so effectively.

Understanding State

Everything in React revolves around state. State represents the underlying data that influences what the user sees on screen.
Common examples of state include:

  • Current User
  • Theme (Light/Dark)
  • Shopping Cart items
  • Authentication Status
  • Notifications
  • Loading Status
  • Search Query.

At any point in time, there exists only one correct UI for the current application state. Conceptually, React behaves like a mathematical function UI = f(State) This expression is one of the most important mental models in React. If the state changes, the output of the function changes. When the output changes, React recalculates the user interface. This principle is the foundation of the entire rendering process.

Components Are Pure Descriptions

Developers assume components generate HTML directly. They do not.
A React component is simply a JavaScript function that returns a description of the desired interface. For example:

function Welcome() {
    return <h1>Hello World</h1>;
}
Enter fullscreen mode Exit fullscreen mode

Internally, React does not immediately create an h1 DOM element. Instead, JSX is transformed into JavaScript:

React.createElement(
    "h1",
    null,
    "Hello World"
);
Enter fullscreen mode Exit fullscreen mode

The output of React.createElement is not a DOM node—it is a plain JavaScript object called a React Element. A simplified representation looks like this:

{
    "type": "h1",
    "props": {
        "children": "Hello World"
    }
}
Enter fullscreen mode Exit fullscreen mode

This object serves as a blueprint describing what should eventually appear on the screen. React builds and compares these descriptions before deciding whether any real DOM updates are necessary.

JSX Is Not HTML

Although JSX resembles HTML, it is not HTML. The browser has no understanding of JSX syntax. When you write:
<div>Hello</div>
he browser never receives this code. During compilation, JSX is transformed into standard JavaScript instructions that React can interpret.
This distinction explains why JSX supports embedding JavaScript expressions seamlessly:
<h1>{user.name}</h1>
React evaluates the JavaScript expression first, then incorporates the result directly into the UI description.

The Rendering Process

Rendering is often misunderstood. Many developers assume rendering means updating the browser DOM. In React, rendering is simply the process of executing component functions to determine what the UI should look like.
The rendering pipeline flows through these distinct stages:

Plaintext
Application State Changes
            
            
React schedules an update
            
            
Component functions execute again
            
            
React creates a new tree of React Elements
            
            
React compares the new tree with the previous tree
            
            
Necessary DOM mutations are identified
            
            
Browser updates the DOM
            
            
Browser paints pixels on the screen
Enter fullscreen mode Exit fullscreen mode

Notice that the browser only becomes involved near the very end of the process. Most of React's work happens entirely in JavaScript memory before any DOM operation occurs.

Rendering Is Not the Same as Updating the DOM

This distinction cannot be overstated: every render does not imply a DOM update. A component may render multiple times while the real DOM remains completely untouched.
Consider this example:

function Example() {

    console.log("Rendering...");

    return <h1>Hello</h1>;

}
Enter fullscreen mode Exit fullscreen mode

Each render executes the Example function again, printing "Rendering..." to the console. However, if the resulting UI description matches the previous one, React determines that no DOM mutation is necessary. This optimization is one reason React applications remain performant despite frequent renders.

A Walk Through setState

Let's re-examine our Counter component:

function Counter() {

    const [count, setCount] = React.useState(0);

    return (
        <>
            <h1>{count}</h1>

            <button
                onClick={() => setCount(count + 1)}
            >
                Increment
            </button>
        </>
    );

}
Enter fullscreen mode Exit fullscreen mode

When the user clicks the Increment button, the following sequence occurs:

  • The click handler runs.
  • setCount() tells React that the state has changed.
  • React marks this component to be updated.
  • React plans a new render.
  • The Counter function runs again.
  • React creates a new set of UI instructions.
  • React compares the old UI description with the new one.
  • React sees that only the number text changed.
  • React updates that specific text in the DOM.
  • The browser shows the new screen.

Notice that React never recreates the entire application. It computes the minimal set of changes required to synchronize the UI with the latest application state.

Thinking Like React

A useful way to understand React is to imagine it asking the same question repeatedly:

Given the current application state, what should the interface look like?

It does not ask:

  • Which button changed?
  • Which div should I update?
  • Which paragraph should I remove?

Those implementation details are React's responsibility. Your responsibility as a developer is to describe the desired interface. When developers adopt this mindset, concepts such as rendering cycles, memorization, reconciliation, and hooks become much easier to understand.

Common Misconceptions

❌ React re-renders the entire page.
Incorrect:
React re-executes component functions to compute a new UI description. Whether the DOM changes depends on the comparison between the previous and current UI trees.
❌ Rendering is expensive.
Incorrect:
Rendering is primarily lightweight JavaScript computation. The truly expensive operations in modern browsers are unnecessary DOM mutations, layout recalculations (reflows), and browser painting.
❌ JSX is HTML.
Incorrect:
JSX is syntactic sugar that is transformed into standard JavaScript function calls before the browser executes the application.
❌ Calling setState immediately changes the DOM.
Incorrect:
State updates are scheduled. React computes the next UI description before committing any changes to the actual DOM.

Key Takeaways

  • State drives rendering: React's primary responsibility is computing the next UI, not manipulating the DOM directly UI = f(State).
  • Components return descriptions: Components are pure functions that describe the interface for a given state using React Elements.
  • JSX is JavaScript: JSX is compiled into JavaScript during build time and never reaches the browser as raw HTML.
  • Rendering is computation: Rendering is the process of executing component functions to compute the next UI description.
  • Render not equals DOM Mutation: A render pass does not necessarily result in DOM mutations if the UI tree hasn't structurally changed.
  • Surgical Updates: React updates only the specific parts of the DOM that actually need to change.

Top comments (1)

Collapse
 
dtofficial profile image
Ogunlari Ololade

@roman_riaboshtan here is part 2
thanks for feedbacks