Mahamudul Hasan Rubel
HomeAboutProjectsSkillsExperienceBlogCoursesPhotosContact
Mahamudul Hasan Rubel

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

Navigation

  • Home
  • About
  • Projects
  • Skills
  • Experience
  • Blog
  • Courses
  • 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
Lesson 17 of the React Fundamentals: Build Modern UIs from Scratch course
ReactJune 25, 20264 min read

Updating State Based on Previous State: A React Best Practice

Learn how to use the functional update pattern in React to safely modify state based on previous values, avoiding common bugs and stale state pitfalls.

ReactuseStatestate managementfunctional programmingweb developmentjavascriptfrontend

Previously in this course, we covered the basics of managing state with useState. While setting a static value is straightforward, real-world applications often require us to increment counters, toggle flags, or append items to lists based on their current value.

In this lesson, we’ll move beyond simple assignment and master the functional update pattern to ensure our state changes are always predictable and bug-free.

The Problem: Why Direct Updates Fail

When you update state using the standard setter function—like setCount(count + 1)—you are telling React what the new value should be. This works perfectly fine for most simple interactions. However, React performs state batching to optimize performance.

If you trigger multiple updates in quick succession, or if your update logic depends on a value that might have changed since the last render, you risk working with "stale" state. Imagine you have a "Like" button that increments a counter. If you fire three clicks instantly, using the simple setter approach might result in your state only incrementing by one, because each call is looking at the same initial count value from the previous render cycle.

Introducing the Functional Update Pattern

To solve this, React allows you to pass a function to your setter instead of a raw value. This is known as the functional state update.

When you pass a function, React guarantees that the argument provided to that function is the latest version of the state, regardless of batching or asynchronous timing.

Worked Example: The Movie Watchlist Counter

In our ongoing movie-browser project, let's add a "Watchlist" counter to our header. Every time a user clicks "Add to Watchlist," we need to increment the count.

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

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

  const handleAdd = () => {
    // Instead of: setCount(count + 1)
    // We use the functional update pattern:
    setCount((prevCount) => prevCount + 1);
  };

  return (
    <button onClick={handleAdd}>
      Add to Watchlist ({count})
    </button>
  );
}

By using (prevCount) => prevCount + 1, we tell React: "Whatever the count is right now, take that value and add one to it." This ensures that even if handleAdd is called multiple times rapidly, each call waits for the previous one to finish, resulting in an accurate total.

Hands-on Exercise

Let’s apply this to our movie browser. Open your MovieCard component. Add a "Like" count to each card.

  1. Create a likes state initialized to 0.
  2. Add a button that increments the likes state.
  3. Crucial: Use the functional update pattern (setLikes(l => l + 1)) to ensure the counter increments correctly even if the user clicks rapidly.
  4. Verify that the UI updates correctly without any lag or skipped integers.

Common Pitfalls

Even experienced developers trip over these three common issues:

  • Mixing Patterns: Don't mix raw values and functional updates in the same logic chain. If you are calculating the next state based on the current one, always use the functional pattern.
  • Assuming Synchronicity: Remember that calling setCount does not update the count variable immediately. The component will re-render with the new value, but the current function execution will still see the old count. This is why the function parameter prevCount is essential—it bypasses this limitation.
  • Over-complicating: If your new state value does not depend on the previous state (for example, resetting a search input to an empty string), you don't need the functional update. Just use setSearch(''). Using it unnecessarily won't break your code, but it adds visual noise.

Best Practices Recap

Following these rules will keep your state management professional and robust:

  1. Always use the functional update whenever the new state depends on the previous state.
  2. Name your parameter clearly—prev or prevCount are standard conventions that make your code readable.
  3. Keep the update logic pure. The function you pass to setCount should be a pure calculation. Do not perform side effects (like API calls) inside this update function; those belong in useEffect.

By adopting these best practices, you eliminate a massive category of intermittent bugs that are notoriously difficult to debug in larger applications.

Up next: We’ll use this foundation to start Filtering the Movie List based on user input, where managing state dependencies becomes even more critical.

Previous lessonHandling Click EventsNext lesson Filtering the Movie List
Back to Blog

Similar Posts

ReactReactJune 25, 20263 min read

Fetching Data from an API: A Practical React Guide

Master the fetch API in React to retrieve external data. Learn to perform asynchronous requests and store JSON responses in your component state effectively.

Read more
ReactJune 25, 20263 min read

Prop Drilling and Context API: Simplifying React State Sharing

Part of the course

React Fundamentals: Build Modern UIs from Scratch

beginner · Lesson 17 of 49

  1. 1

    Introduction to Component-Based Architecture

    4 min
  2. 2

    Understanding the Virtual DOM

    4 min
  3. 3

    Setting Up with Vite

    3 min

Learn to stop prop drilling in your React applications. Discover how the Context API lets you share data globally without manual prop passing.

Read more
ReactReactJune 25, 20263 min read

Building a Movie Filter Toggle in React: A Beginner's Guide

Master the art of UI state management by adding a filter toggle to your movie app. Learn to control list rendering using boolean state and checkbox inputs.

Read more
4

Mastering JSX Syntax

4 min
  • 5

    Creating Static Components

    3 min
  • 6

    Styling Components

    3 min
  • 7

    Passing Data with Props

    3 min
  • 8

    Dynamic Movie Cards

    3 min
  • 9

    Component Composition

    3 min
  • 10

    Conditional Rendering

    3 min
  • 11

    Rendering Lists of Data

    4 min
  • 12

    The Key Prop Explained

    4 min
  • 13

    Introduction to React State

    4 min
  • 14

    Managing State with useState

    3 min
  • 15

    Building an Interactive Search Bar

    3 min
  • 16

    Handling Click Events

    4 min
  • 17

    Updating State Based on Previous State

    4 min
  • 18

    Filtering the Movie List

    3 min
  • 19

    Handling Form Submissions

    3 min
  • 20

    Controlled Components

    4 min
  • 21

    Event Bubbling and Propagation

    3 min
  • 22

    Building a Movie Filter Toggle

    3 min
  • 23

    Introduction to Side Effects

    4 min
  • 24

    useEffect Dependencies

    4 min
  • 25

    Fetching Data from an API

    3 min
  • 26

    Handling Loading States

    3 min
  • 27

    Managing Errors

    3 min
  • 28

    Cleanup Functions in useEffect

    3 min
  • 29

    Debouncing Search Input

    3 min
  • 30

    Refactoring for Clean Code

    3 min
  • 31

    Folder Structure Best Practices

    4 min
  • 32

    Extracting Custom Hooks

    3 min
  • 33

    Prop Drilling and Context API

    3 min
  • 34

    Polishing the UI

    Coming soon
  • 35

    Finalizing the Movie Browser

    Coming soon
  • 36

    Review of Component Lifecycle

    Coming soon
  • 37

    Review of State Management

    Coming soon
  • 38

    Building a Modal Component

    Coming soon
  • 39

    Introduction to PropTypes

    Coming soon
  • 40

    Performance Optimization Basics

    Coming soon
  • 41

    Handling Browser History

    Coming soon
  • 42

    Working with LocalStorage

    Coming soon
  • 43

    Building a Favorites List

    Coming soon
  • 44

    Handling Media in React

    Coming soon
  • 45

    Introduction to Testing

    Coming soon
  • 46

    Debugging React Apps

    Coming soon
  • 47

    Deployment Basics

    Coming soon
  • 48

    Using External Libraries

    Coming soon
  • 49

    Advanced

    Coming soon
  • View full course