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 23, 20264 min read

React state management: Why variables reset and how to fix it

React state management can be confusing when your variables keep resetting. Learn why React state updates trigger re-renders and how to master snapshots.

ReactuseStateJavaScriptFrontendWeb DevelopmentNext.jsTutorial

I remember sitting with a junior dev a few months ago, watching them pull their hair out over a counter component. They had declared let count = 0 inside their function component, incremented it on a button click, and were baffled why the screen never updated. It’s a classic rite of passage. If you’ve ever wondered why your variables disappear the moment your UI refreshes, you’re hitting the core of the React mental model.

The short answer? Your component isn't a persistent object; it's a function that gets called over and over again. Every time React needs to update the view, it executes your function from top to bottom. Any standard variable initialized inside that function is recreated from scratch.

Why variables vanish during component rendering

When you write a function component, think of it as a snapshot. When a state change occurs, React doesn't just "update" the existing component. It throws the old one away and calls your function again to generate a new UI representation.

If you write this:

JAVASCRIPT
function Counter() {
  let count = 0; // This resets every single time
  
  return (
    <button onClick={() => count++}>
      Count: {count}
    </button>
  );
}

Every time you click that button, React triggers a re-render. Your count variable is set back to 0 before the function even finishes. Even though you incremented it, the memory location for that count variable is wiped clean because it's local to the function scope. This is why understanding React rendering: Why state updates re-run your components is crucial—if you treat components like traditional classes with persistent properties, you’re going to have a bad time.

Persisting data with the useState hook

To keep data alive between these function calls, we need a way to tell React: "Hey, keep this value in memory even after the function finishes." That is exactly what the useState hook does.

When you use useState, you’re essentially asking React to manage a piece of data for you outside of the function's immediate scope.

JAVASCRIPT
import { useState } from CE9178">'react';

function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <button onClick={() => setCount(count + 1)}>
      Count: {count}
    </button>
  );
}

Now, when setCount is called, React stores the new value, triggers a re-render, and when your function runs again, useState returns the persisted value instead of the initial one. It’s the bridge that connects the static nature of functional components to the dynamic nature of user interaction. If you want to dive deeper into how this works under the hood, check out React rendering: Mastering State Batching and the Two-Pass Model to see how React handles these updates efficiently.

The Snapshot Mental Model

Here’s the shift you need to make: stop thinking of count as a variable that changes. Think of count as a constant for that specific render.

In any single render of your component, the value of count is immutable. If you have an alert or a setTimeout inside your function, it will "capture" the value of count as it existed at the exact moment that specific render occurred.

We’ve covered this concept in detail in React State Snapshots: A Mental Model for Functional Components, but the takeaway is simple: React state updates are essentially requests for a new render with new data.

Common pitfalls with state updates

A common mistake I see is trying to mutate state directly or assuming the state updates instantly. Because of how React batches updates, calling setCount(count + 1) three times in a row won't result in +3. React batches these to optimize performance, which is why React Rendering: How State Updates and Reconciliation Work is such a vital topic to master.

If you need to perform multiple updates, always use the functional updater pattern:

JAVASCRIPT
setCount(prevCount => prevCount + 1);
setCount(prevCount => prevCount + 1);
setCount(prevCount => prevCount + 1);

By passing a function to the setter, you ensure you're working with the most recent state value rather than the stale snapshot from the current render.

FAQ: Clearing up the confusion

Why doesn't my variable update on the screen? Because React doesn't know you changed a local variable. It only triggers a re-render (and updates the DOM) when you use the setter function provided by useState.

Can I use a variable if I don't need it to trigger a re-render? Yes, but don't use useState. Use useRef. It persists values across renders without triggering a re-render when the value changes. It's perfect for things like timers or DOM element references.

Does React re-run the entire component tree? Not necessarily. React is smart about reconciliation, but conceptually, you should write your components assuming they could be re-run at any time. Keep them pure and free of side effects.

I still occasionally catch myself trying to update a local variable when I’m tired or rushing. It happens. The key is remembering that your component function is just a factory for UI snapshots. If you need data to survive the journey from one snapshot to the next, hook into React’s memory, not your own local scope.

Back to Blog

Similar Posts

ReactJune 23, 20265 min read

React Reconciliation: How to Control Component Identity and Lifecycles

Master React reconciliation to control how your UI components stay, update, or get destroyed. Stop losing state during re-renders by mastering component identity.

Read more
ReactNext.jsJune 22, 20264 min read

React derived state: Stop using useEffect for data calculations

React derived state is the key to faster components. Learn how to stop abusing useEffect for data transformations and simplify your React performance optimization.

Read more
ReactNext.jsJune 22, 20264 min read

Next.js Hydration Mismatch: Why Components Render Twice and Syncing Fixes

Next.js hydration errors happen when the server and client disagree. Learn how to debug React hydration mismatch and sync your components for faster apps.

Read more