DEV Community

Cover image for Stop Waiting for APIs: Unlock Instant Speed with React's Optimistic Updates
Werliton Silva
Werliton Silva

Posted on

Stop Waiting for APIs: Unlock Instant Speed with React's Optimistic Updates

Tchaca was developing a new feature and noticed something annoying: every time a user clicked "like," the interface would take a few seconds to respond while waiting for the server. During that time, the screen seemed frozen, and the experience was frustrating.

wait

She thought, "Do I really need to wait for the server to show what the user already knows they requested?" 🤔

That's when she discovered optimistic updates - a way to make the interface feel more fluid, giving the impression of an immediate response, even before the server actually confirms it.


In web applications, the latency between the client and server can significantly impact user experience. Optimistic updates are a powerful technique to improve perceived performance by updating the interface before the server confirms the action.

Concept

An optimistic update involves immediately updating the local state after a user action, assuming the server operation will succeed. If the server confirms, the UI remains unchanged; if it fails, the update is rolled back.

Final Result

res

This technique is especially useful for fast interactions such as:

  • Liking posts
  • Adding items to a shopping cart
  • Voting in polls
  • Updating lists

Benefits

  1. Perceived speed: users see changes instantly.
  2. Smooth experience: avoids a “frozen” UI while waiting for the server.
  3. Easy rollback: reversing a failed action is straightforward.

Practical Example

Without Optimistic Update

function App() {
  const [likes, setLikes] = React.useState(0);

  function addLike() {
    fakeApiCall().then(() => {
      setLikes(likes + 1); // Updates only after server response
    });
  }

  return (
    <div>
      <p>{likes} Likes</p>
      <button onClick={addLike}>Like</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

In this approach, the UI only updates after the server responds, causing noticeable delays if the API is slow.


With Optimistic Update

function App() {
  const [likes, setLikes] = React.useState(0);

  function addLike() {
    // Update locally immediately
    setLikes(prev => prev + 1);

    // Call the server
    fakeApiCall().catch(() => {
      // Rollback if there’s an error
      setLikes(prev => prev - 1);
    });
  }

  return (
    <div>
      <p>{likes} Likes</p>
      <button onClick={addLike}>Like</button>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

Technical tip: using the callback version of setLikes (prev => prev + 1) ensures state consistency even with rapid multiple interactions.


Technical Considerations

  1. Efficient rollback: always plan to revert the UI on errors.
  2. Avoid inconsistencies: use previous-state updates (prev) to prevent race conditions.
  3. Backend synchronization: logging or event queues can help reconcile states if multiple updates fail.
  4. Cache management: libraries like React Query, SWR, or Apollo Client provide built-in support for optimistic updates and automatic server sync.

When to Use

  • Fast and predictable server operations.
  • Interactions that don’t require immediate confirmation.
  • Cases where a fast UX outweighs immediate absolute consistency.

Technical Summary:

Optimistic updates in React let the local state be updated before the server responds, improving UX and perceived performance. If the server operation fails, the UI is reverted, ensuring consistency.

Top comments (0)