How React Renders the UI
Ali Aslam

Ali Aslam @a1guy

About: https://www.linkedin.com/in/maliaslam/

Joined:
Aug 9, 2025

How React Renders the UI

Publish Date: Aug 15
1 0

In React, every time something changes — whether it's a button click, a form submission, or a data update — the UI needs to reflect those changes. But how does React figure out what needs to change and how to apply those updates quickly and efficiently?

Understanding React’s rendering pipeline is the key to unlocking how React works its magic. In this article, we’ll walk you through the process of how React handles state changes, triggers re-renders, and makes updates to the UI in the most optimal way possible. You'll learn:

  • How React determines what needs to be updated when state changes.
  • The concept of reconciliation and how it helps React perform efficiently.
  • How React applies minimal changes to the real DOM to keep things snappy.

By the end, you'll have a deep understanding of how React renders UI and why it's so fast at doing it.

Let’s dive into the details!


Step 1: State Changes in React

In React, state is the data that determines how your components look and behave. When state changes, React triggers a re-render to reflect the updates in the UI.

What Happens When State Changes?

When you call the setState() function (or use the useState hook), React goes through several steps:

  1. Updates State: The component's state changes based on the new value you set.
  2. Triggers a Re-render: React marks the component as “dirty” (needing a re-render) and schedules an update. It doesn't immediately re-render, though; React batches updates to optimize performance.
  3. Runs the Component Again: React calls the component function again with the new state, generating the new JSX.

Example: State Update

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

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
  1. When you click the button, setCount(count + 1) updates the count state.
  2. React queues a re-render of the Counter component, and the new state (count + 1) is used to update the <h1> tag.

Step 2: Re-rendering — What React Does When State Changes

When a component re-renders, React follows these steps:

1. Check for Changes:

React checks if the component's state or props have changed. If not, React skips the re-rendering of that component and its children.

2. Rebuild JSX:

React runs your component again, using the new state, and generates new JSX.

3. Create New Virtual DOM Tree:

React creates a new Virtual DOM tree that represents the updated UI.

4. Diffing:

React compares the old Virtual DOM tree to the new one. This is where the diffing algorithm comes into play. It determines the minimal set of changes needed and creates an update plan.


Step 3: Reconciliation — The Smart Way React Updates the DOM

Reconciliation is React’s process of efficiently updating the real DOM. This process ensures that React only updates the parts of the UI that need to change, without disturbing the rest of the UI.

Here’s how reconciliation works:

  1. Compare Old and New Virtual DOM:
    React compares the old Virtual DOM to the new Virtual DOM tree (which was generated during the re-rendering phase).

  2. Find Differences:
    React identifies differences between the two trees and marks only the changed parts.

  3. Generate Update Instructions:
    React creates an update instruction set that tells the browser exactly which elements to change.

  4. Apply Changes to the Real DOM:
    React updates the real DOM using the instructions generated during the diffing process. These updates happen in batches, reducing the performance cost.


Example: Reconciliation in Action

Consider this example where the list changes based on state:

function ItemList() {
  const [items, setItems] = useState(['Apple', 'Banana', 'Cherry']);

  const addItem = () => setItems([...items, 'Date']);

  return (
    <div>
      <button onClick={addItem}>Add Item</button>
      <ul>
        {items.map((item, index) => <li key={index}>{item}</li>)}
      </ul>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

When the Add Item button is clicked:

  1. State Updates: The setItems function updates the state, adding a new item ('Date').
  2. Re-render: The component re-renders with the new list, which includes the new item.
  3. Reconciliation: React compares the old list with the new list, recognizes that only one new item was added, and efficiently updates the DOM to show the new item without touching the rest of the list.

Step 4: Rendering Pipeline — How React Brings It All Together

Now that we know how state updates, re-renders, and reconciliation work, let’s look at the full rendering pipeline from start to finish:

  1. State Update:
    A user interaction (like clicking a button) triggers a state update (e.g., setCount).

  2. Re-rendering:
    React re-runs the component with the new state, generating new JSX.

  3. Virtual DOM Creation:
    React creates a new Virtual DOM tree with the updated UI.

  4. Diffing and Reconciliation:
    React compares the new Virtual DOM tree with the previous one, calculates the differences, and prepares the update instructions.

  5. Update the Real DOM:
    React applies the minimal set of changes to the real DOM to make the UI match the new Virtual DOM.

  6. Repaint:
    Finally, the browser renders the updated UI, and you see the changes instantly.


⚠️ React 19 and Concurrent Rendering

With React 19, this process has become even more efficient thanks to concurrent rendering. React can now prioritize important updates over less critical ones.

For example, if you're typing in a text box while an image is loading, React can pause rendering the image and continue with the text box updates, making sure the UI feels snappy and responsive.

This interruptible rendering is part of React 19’s concurrent rendering improvements, making the entire process smoother than ever.


Performance Optimization Tips

While React’s rendering pipeline is already optimized, there are a few things you can do to make your app even faster:

1. Memoize Components with React.memo

If a component’s output is based solely on props, you can prevent unnecessary re-renders by wrapping it in React.memo:

const MemoizedComponent = React.memo(function MyComponent(props) {
  return <div>{props.text}</div>;
});
Enter fullscreen mode Exit fullscreen mode

This tells React to skip rendering the component unless the props have changed.

2. Optimize List Rendering with key Prop

For dynamic lists, always provide a unique key prop to help React efficiently identify and update list items:

{items.map(item => <li key={item.id}>{item.name}</li>)}
Enter fullscreen mode Exit fullscreen mode

Using the key prop allows React to track changes in the list and avoid unnecessary DOM operations.

3. Use Lazy Loading and Code Splitting

React 19 introduces Suspense for code splitting. You can dynamically load parts of your app as needed, reducing initial load time.

Wrapping Up React’s Rendering Pipeline

By understanding the rendering pipeline, you can now appreciate how React efficiently updates the UI without unnecessary re-renders, ensuring your apps remain fast and responsive.

Key Takeaways:

  • State changes trigger re-renders, but React only updates the parts of the UI that need to change, using a process called reconciliation.
  • React uses the Virtual DOM to compare the old and new UI, applying the smallest set of updates to the real DOM.
  • Concurrent rendering in React 19 makes the app feel more responsive by prioritizing critical updates, like user interactions, over less important ones.
  • React.memo, useMemo, and useCallback can help you optimize performance by preventing unnecessary renders.

What’s Next?

Now that you’ve got a solid grasp of how React updates the UI, it’s time to level up and learn about React Hooks, the powerful tools that let you manage state, side effects, and more in a functional way. Get ready to make your components even more dynamic and maintainable.

Up Next:
Mastering React Hooks →


Follow me on DEV for future posts in this deep-dive series.
https://dev.to/a1guy
If it helped, leave a reaction (heart / bookmark) — it keeps me motivated to create more content
Want video demos? Subscribe on YouTube: @LearnAwesome

Comments 0 total

    Add comment