Mahamudul Hasan Rubel
HomeAboutProjectsSkillsExperienceBlogPhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • About
  • Projects
  • Skills
  • Experience
  • Blog
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
ReactJune 22, 20264 min read

React rendering: Why state updates re-run your components

React rendering logic can be confusing. Learn why React state updates trigger component re-renders and how to master the reconciliation process for better UI.

ReactFrontend DevelopmentJavaScriptWeb PerformanceState ManagementNext.jsTutorial

I remember sitting through my first production bug hunt where a simple counter button kept resetting its value. I was convinced it was a race condition in the API layer, but after two days of debugging, I realized I didn't actually understand how React rendering worked. I thought the component was a persistent object, but it's actually just a function that runs over and over again.

If you’re a junior developer, you’ve likely been told that "state updates trigger re-renders." But what does that actually mean for your code? Let’s pull back the curtain on the render phase.

The Component as a Snapshot

In React, a component is just a plain JavaScript function. When you call useState, you’re asking React to keep track of a value for that specific component instance. When you call the setter function—like setCount(count + 1)—you’re telling React: "Hey, something changed. Please run this function again so we can see what the UI should look like now."

Crucially, React state updates don't just "change" the component. They discard the old execution context and create a fresh one. Every variable inside your component function—unless it’s stored in a useRef—is re-initialized from scratch every single time the function runs. If you want to understand how this survives between cycles, check out my notes on React reconciliation and component state persistence: A mental model.

Predicting Component Re-renders

Think of the render phase as a two-step process:

  1. The Trigger: An event (a state change, a parent re-render, or a context update) tells React it’s time to update.
  2. The Render: React calls your component function. It captures the returned JSX—a snapshot of what the UI should be right now.

I see many juniors try to manually "force" updates to DOM nodes, but that’s the wrong path. If you find yourself reaching for the DOM directly, you’re fighting the framework. Instead, learn how React rendering: Mastering State Batching and the Two-Pass Model handles these updates efficiently.

Here’s a quick mental check. If you have this code:

JAVASCRIPT
function Counter() {
  const [count, setCount] = useState(0);
  console.log("Rendering! Count is:", count);

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

Every time you click that button, your terminal prints "Rendering! Count is: X". It’s not just updating the button text; it’s executing the entire function body again. If you had an expensive calculation in there, it would run every single time.

The Reconciliation Engine

Once React has the new snapshot of your UI, it compares it to the previous one. This is the React virtual DOM in action. It calculates the minimum number of changes needed to sync the real browser DOM with your new component snapshot.

We used to worry about the performance cost of this comparison, but in modern React (version 18+), this process is incredibly fast. Most performance issues I see aren't caused by the reconciliation itself, but by developers doing heavy work inside the render function that doesn't belong there.

If you're curious about why your variables seem to "forget" their values, it's because they are being re-declared. You might need to look into how React useRef and Component Memory: Why Variables Reset on Re-render can help you persist values without triggering new renders.

Common Traps

Early in my career, I tried to store "state" in a global variable outside the component. Don't do this.

  • The Problem: Global variables don't trigger re-renders. Your UI will be out of sync with your data.
  • The Fix: Always use useState or useReducer for data that needs to reflect in the UI.
  • The Gotcha: Don't put logic that should be in an useEffect directly in the component body. It will run on every render, which often leads to infinite loops.

FAQ: Frequently Asked Questions

Does every state update cause a full page refresh? No. React only updates the specific DOM nodes that changed based on the diffing process. The rest of your page remains untouched.

Why does my component re-render when its parent does? By default, React re-renders all children whenever a parent component re-renders. If this is causing performance issues, look into React.memo, but don't optimize prematurely.

Is the Virtual DOM still relevant? Yes, it's the conceptual model for how React performs its "diffing" or reconciliation. Even though React Fiber makes this more complex under the hood, thinking of it as a tree-comparison tool is still the best way to predict UI behavior.

Moving Forward

I still catch myself writing code that triggers unnecessary re-renders. It happens to the best of us. The key is to stop seeing the component as a static object and start seeing it as a function that reacts to state changes.

Next time you're stuck, add a console.log at the top of your component function. If it’s firing more often than you expect, you’ve likely found a state update loop. Don't be afraid to pull apart your components into smaller pieces; it usually makes the render flow much easier to trace.

Back to Blog

Similar Posts

ReactNext.jsJune 21, 20264 min read

React State Synchronization: How to Avoid Infinite Loops

Master React state synchronization by avoiding unnecessary useEffect calls. Learn to handle dependent inputs correctly and keep your components predictable.

Read more
ReactNext.js
June 22, 2026
4 min read

React rendering: Mastering State Batching and the Two-Pass Model

React rendering follows a two-pass mental model involving state batching and reconciliation. Learn how React Fiber manages the render and commit phases.

Read more
ReactNext.jsJune 21, 20264 min read

React lifecycle: Mastering Mounting, Updating, and Unmounting

Master the React lifecycle to write predictable code. Learn how to handle component mounting, updating, and unmounting to avoid common memory leaks.

Read more