Falytom logoFALYTOM
Games
ToolsUI ComponentsServicesProductsAbout
LoginSign Up
menu
  1. Home
  2. /Web Development
  3. /React
  4. /State Updates Rerenders
Your Progress0%
0 of 42 completed

React Topics

Getting Started

  • What is React?
  • React vs Vanilla JavaScript
  • Setting Up Your Environment
  • Your First React App

JSX Fundamentals

  • Introduction to JSX
  • JSX Expressions and Variables
  • Conditional Rendering
  • Lists and Keys
  • Styling in JSX

Components Basics

  • Function Components
  • Props
  • Children Prop
  • Props Destructuring
  • Component Composition

State Management

  • Introduction to State
  • useState Hook
  • State Updates and Re-renders
  • Multiple State Variables
  • State Best Practices

Events and Interactivity

  • Handling Events
  • Event Objects
  • Forms in React
  • Form Validation

Side Effects and Data

  • Introduction to useEffect
  • Data Fetching
  • Cleanup Functions
  • Dependency Arrays

Advanced Hooks

  • useRef Hook
  • useContext Hook
  • useMemo Hook
  • useCallback Hook

React Patterns

  • Custom Hooks
  • Higher-Order Components
  • Render Props Pattern

React Router

  • Introduction to React Router
  • Routes and Navigation
  • Dynamic Routes and Parameters

Best Practices

  • Component Organization
  • Performance Optimization
  • Error Handling
  • Testing React Components

Real World Project

  • Building a Complete App

State Updates and Re-renders

How React updates the UI efficiently

You know how to create and update state with useState, but what actually happens when state changes? How does React know to update the UI? And why do state updates sometimes behave unexpectedly? In this lesson, you'll learn about the render cycle, how React efficiently updates the DOM, why state updates are batched, and how to avoid common performance issues. Understanding re-renders is key to writing efficient React applications.

What is a "Render"?

In React, a "render" means calling your component function to get the JSX that should be displayed:

what-is-render.jsx
function Counter() {
  console.log('Rendering Counter...')  // This logs on every render
  
  const [count, setCount] = React.useState(0)
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  )
}

// Render sequence:
// 1. Initial render: "Rendering Counter..." (count = 0)
// 2. Click button: setCount(1) is called
// 3. React re-renders: "Rendering Counter..." (count = 1)
// 4. Click again: setCount(2) is called
// 5. React re-renders: "Rendering Counter..." (count = 2)

A render is NOT the same as updating the DOM:

  • Render - React calls your component function to get JSX
  • Commit - React updates the actual DOM based on changes
  • React is smart: it only updates DOM elements that actually changed

The Render Cycle

Here's what happens when state changes:

  1. Trigger - State update triggers a re-render
  2. Render - React calls your component function
  3. Commit - React updates the DOM if needed
  4. Browser Paint - Browser displays the changes
render-cycle.jsx
function Example() {
  const [count, setCount] = React.useState(0)
  
  console.log('1. Component rendering, count =', count)
  
  const handleClick = () => {
    console.log('2. Before setState, count =', count)
    setCount(count + 1)  // Trigger re-render
    console.log('3. After setState, count =', count)  // Still old value!
  }
  
  console.log('4. Rendering complete')
  
  return <button onClick={handleClick}>{count}</button>
}

// When you click:
// Console output:
// "2. Before setState, count = 0"
// "3. After setState, count = 0"  ← State not updated yet!
// "1. Component rendering, count = 1"  ← Re-render with new state
// "4. Rendering complete"

// Key insight: State updates are asynchronous
// The component re-renders AFTER the event handler finishes

Why State Updates Are Asynchronous:

React batches multiple state updates together for better performance. Instead of re-rendering after each setState, React waits until your event handler finishes, then does one re-render with all the updates combined. This is much more efficient!

State Update Batching

React automatically batches multiple state updates that happen in the same event handler:

Single Re-render for Multiple Updates

batching.jsx
function Example() {
  const [count, setCount] = React.useState(0)
  const [flag, setFlag] = React.useState(false)
  
  console.log('Rendering...')  // How many times does this log?
  
  const handleClick = () => {
    setCount(count + 1)  // Schedule update
    setFlag(!flag)       // Schedule update
    setCount(count + 2)  // Schedule update
    // React batches these together
    // Only 1 re-render happens, not 3!
  }
  
  return (
    <div>
      <p>Count: {count}</p>
      <p>Flag: {String(flag)}</p>
      <button onClick={handleClick}>Update</button>
    </div>
  )
}

// Click button once:
// Console: "Rendering..." (only once!)
// Not three times

// This is automatic batching for better performance

Batching with Function Updates

batching-functions.jsx
function Counter() {
  const [count, setCount] = React.useState(0)
  
  const incrementThreeTimes = () => {
    // ❌ These don't work as expected
    setCount(count + 1)  // Uses count = 0
    setCount(count + 1)  // Still uses count = 0
    setCount(count + 1)  // Still uses count = 0
    // Result: count becomes 1, not 3
  }
  
  const incrementThreeTimesProperly = () => {
    // ✅ These work correctly
    setCount(prev => prev + 1)  // prev = 0, sets to 1
    setCount(prev => prev + 1)  // prev = 1, sets to 2
    setCount(prev => prev + 1)  // prev = 2, sets to 3
    // Result: count becomes 3
  }
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={incrementThreeTimes}>+3 (Broken)</button>
      <button onClick={incrementThreeTimesProperly}>+3 (Works)</button>
    </div>
  )
}

💡 Batching Rule of Thumb

React batches updates in:
✅ Event handlers (onClick, onChange, etc.)
✅ useEffect callbacks
✅ setTimeout/setInterval callbacks (React 18+)
✅ Promise callbacks (React 18+)

In React 18+, batching happens almost everywhere automatically!

When Does React Re-render?

React re-renders a component when:

  • State changes - You call a state setter function
  • Props change - Parent passes different props
  • Parent re-renders - Parent component re-renders
  • Context changes - Context value changes (we'll learn this later)

Example: State Changes

state-rerenders.jsx
function Counter() {
  const [count, setCount] = React.useState(0)
  console.log('Counter rendering, count =', count)
  
  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  )
}

// Click button:
// Console: "Counter rendering, count = 1"
// Click again:
// Console: "Counter rendering, count = 2"

Example: Props Changes

props-rerenders.jsx
function Child({ value }) {
  console.log('Child rendering, value =', value)
  return <p>Value: {value}</p>
}

function Parent() {
  const [count, setCount] = React.useState(0)
  
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>
        Update Parent
      </button>
      <Child value={count} />
    </div>
  )
}

// Click button:
// Console: "Child rendering, value = 1"
// Child re-renders because its prop changed

Example: Parent Re-renders

parent-rerenders.jsx
function Child() {
  console.log('Child rendering')
  return <p>I am a child</p>
}

function Parent() {
  const [count, setCount] = React.useState(0)
  console.log('Parent rendering')
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
      <Child />  {/* Child has no props! */}
    </div>
  )
}

// Click button:
// Console: "Parent rendering"
// Console: "Child rendering"  ← Re-renders even though props didn't change!

// When parent re-renders, children re-render by default

Same Value Updates

What happens if you update state to the same value it already has?

same-value.jsx
function Example() {
  const [count, setCount] = React.useState(0)
  console.log('Rendering...')
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(0)}>
        Set to 0 (same value)
      </button>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  )
}

// Initial render: "Rendering..."
// Click "Set to 0": "Rendering..." (re-renders once)
// Click "Set to 0" again: (no re-render!)

// React is smart:
// First time setting to same value → re-renders (to be safe)
// Second time → skips re-render (optimization)

🔍 Object.is Comparison

React uses Object.is() to compare old and new state:
Object.is(0, 0) → true (same)
Object.is('hi', 'hi') → true (same)
Object.is({}, {}) → false (different objects!)
Object.is([], []) → false (different arrays!)

This is why you need new objects/arrays to trigger re-renders!

Understanding Render Behavior

Each Render is a Snapshot

snapshot.jsx
function Counter() {
  const [count, setCount] = React.useState(0)
  
  const handleClick = () => {
    // This render's snapshot: count = 0
    setCount(count + 1)
    
    setTimeout(() => {
      // This still uses the OLD snapshot!
      console.log(count)  // Still 0, not 1!
    }, 3000)
  }
  
  return (
    <button onClick={handleClick}>
      Count: {count}
    </button>
  )
}

// Click button, wait 3 seconds:
// Console: 0 (not 1!)

// Why? The timeout captures count from the render when it was created
// Each render has its own "version" of state

State Updates Queue

update-queue.jsx
function Counter() {
  const [count, setCount] = React.useState(0)
  
  const handleClick = () => {
    // Current render: count = 0
    
    // Queue update: 0 + 1 = 1
    setCount(count + 1)
    
    // Queue update: 0 + 1 = 1 (still using old count!)
    setCount(count + 1)
    
    // Result: count becomes 1, not 2
  }
  
  const handleClickProperly = () => {
    // Current render: count = 0
    
    // Queue update: prev(0) + 1 = 1
    setCount(prev => prev + 1)
    
    // Queue update: prev(1) + 1 = 2
    setCount(prev => prev + 1)
    
    // Result: count becomes 2
  }
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={handleClick}>+2 (broken)</button>
      <button onClick={handleClickProperly}>+2 (works)</button>
    </div>
  )
}

Avoiding Unnecessary Re-renders

Problem: Child Re-renders Too Much

unnecessary-rerenders.jsx
function ExpensiveChild({ data }) {
  console.log('ExpensiveChild rendering')
  // Imagine this does heavy calculations
  return <div>{data}</div>
}

function Parent() {
  const [count, setCount] = React.useState(0)
  const [name, setName] = React.useState('')
  
  return (
    <div>
      {/* Unrelated state changes */}
      <input 
        value={name} 
        onChange={e => setName(e.target.value)} 
      />
      
      {/* Child re-renders every time name changes! */}
      <ExpensiveChild data={count} />
      
      <button onClick={() => setCount(count + 1)}>
        Update Count
      </button>
    </div>
  )
}

// Type in input: "ExpensiveChild rendering" (unnecessary!)
// ExpensiveChild re-renders even though its prop (count) didn't change

Solution: React.memo (Preview)

memo-solution.jsx
// We'll learn this in detail later, but here's a preview:

// Wrap component in React.memo
const ExpensiveChild = React.memo(function ExpensiveChild({ data }) {
  console.log('ExpensiveChild rendering')
  return <div>{data}</div>
})

// Now ExpensiveChild only re-renders when 'data' prop changes!
// Typing in input: (no log - doesn't re-render)
// Click button: "ExpensiveChild rendering" (only when needed)

Don't Optimize Too Early!

React is already fast. Don't worry about re-renders until you have an actual performance problem. Premature optimization makes code more complex without real benefits. We'll learn proper optimization techniques in advanced lessons.

Interactive Demo

ReactPlayground.jsx
Code Editor
Preview

💡 Tip: Edit the code above and click "Run" to see your changes

Common Re-render Mistakes

1. Creating Objects/Arrays in Render

mistake-objects.jsx
function Parent() {
  const [count, setCount] = React.useState(0)
  
  // ❌ New object on every render
  const config = { theme: 'dark' }
  
  return <Child config={config} />
}

// Child re-renders every time because config is a new object!

// ✅ Better: Move outside component
const config = { theme: 'dark' }

function Parent() {
  const [count, setCount] = React.useState(0)
  return <Child config={config} />
}

// ✅ Or use useMemo (advanced, we'll learn later)
const config = React.useMemo(() => ({ theme: 'dark' }), [])

2. Inline Function Props

mistake-inline.jsx
function Parent() {
  // ❌ New function on every render
  return <Child onClick={() => console.log('clicked')} />
}

// ✅ Better: Define outside render
function Parent() {
  const handleClick = () => console.log('clicked')
  return <Child onClick={handleClick} />
}

// Note: This usually doesn't matter for performance
// Only optimize if you have actual performance issues

3. Not Using Function Form When Needed

mistake-function-form.jsx
// ❌ Wrong
const increment = () => {
  setCount(count + 1)
  setCount(count + 1)  // Still uses old count
  // Result: +1, not +2
}

// ✅ Correct
const increment = () => {
  setCount(prev => prev + 1)
  setCount(prev => prev + 1)
  // Result: +2
}

Key Takeaways

  • A render means React calls your component function to get JSX
  • State updates trigger re-renders asynchronously
  • React batches multiple state updates into one re-render
  • Each render is a snapshot with fixed state values
  • Use function form setState(prev => ...) when new state depends on previous
  • Components re-render when state, props, or parent changes
  • Setting state to same value may skip re-render (optimization)
  • React uses Object.is() to compare state values
  • Child components re-render when parent re-renders by default
  • Re-renders are usually fast - don't optimize prematurely
  • State updates in timeouts/promises capture state from their render
  • Understanding re-renders helps you write efficient React code

What's Next?

You now understand how React updates the UI when state changes! You know about the render cycle, batching, and when re-renders happen.

But so far we've been using single state variables. What if your component needs multiple pieces of state? Should you use one useState or several? How do you organize state effectively?

In the next lesson, you'll learn about multiple state variables:

  • When to split state into multiple variables
  • When to combine state into objects
  • How to manage related state
  • Best practices for state organization

Get ready to organize your state like a pro! 🎯

Learning how React efficiently updates the UI with state changes!

Previous
useState Hook
Next
Multiple State Variables

Never Miss a New React Tutorial

Join 2,000+ developers learning React step-by-step. Get new tutorials, tips, and exclusive resources delivered to your inbox - completely FREE.

You might also like

UI Components

Ready-made components for your projects

Developer Tools

Boost productivity with handy generators

HTML Game

Learn HTML concepts through interactive gameplay

Join Our Web Development Training Program

Master frontend & backend development with hands-on projects.

React Tutorials

0 of 42 completed

Your Progress0%

Topics

Getting Started

  • What is React?
  • React vs Vanilla JavaScript
  • Setting Up Your Environment
  • Your First React App

JSX Fundamentals

  • Introduction to JSX
  • JSX Expressions and Variables
  • Conditional Rendering
  • Lists and Keys
  • Styling in JSX

Components Basics

  • Function Components
  • Props
  • Children Prop
  • Props Destructuring
  • Component Composition

State Management

  • Introduction to State
  • useState Hook
  • State Updates and Re-renders
  • Multiple State Variables
  • State Best Practices

Events and Interactivity

  • Handling Events
  • Event Objects
  • Forms in React
  • Form Validation

Side Effects and Data

  • Introduction to useEffect
  • Data Fetching
  • Cleanup Functions
  • Dependency Arrays

Advanced Hooks

  • useRef Hook
  • useContext Hook
  • useMemo Hook
  • useCallback Hook

React Patterns

  • Custom Hooks
  • Higher-Order Components
  • Render Props Pattern

React Router

  • Introduction to React Router
  • Routes and Navigation
  • Dynamic Routes and Parameters

Best Practices

  • Component Organization
  • Performance Optimization
  • Error Handling
  • Testing React Components

Real World Project

  • Building a Complete App
Falytom logoFALYTOM

Learn technologies like HTML, CSS, JavaScript, React, NodeJS and more through interactive games, tutorials, components and free tools. Transform your businesses with AI chatbots, SEO-optimized websites, and professional development services.

© 2025 Tomilola Group
  • Facebook logo
  • Twitter logo
  • Instagram logo
  • LinkedIn logo
  • GitHub logo
  • YouTube logo