DEV Community

arafatruetbd
arafatruetbd

Posted on

Smooth UI Updates in React 19 with `useTransition`: A Simple Example

Introduction

  • Context: React 19 introduced built-in support for async functions inside transitions, enabling automatic handling of loading states, errors, and form submissions by leveraging the useTransition hook.
  • Why it matters: This feature dramatically reduces boilerplate and helps your app remain responsive during asynchronous updates.

Quick Explanation of useTransition

  • useTransition returns a tuple:
  const [isPending, startTransition] = useTransition();
Enter fullscreen mode Exit fullscreen mode
  • startTransition: wrap your state updates to mark them as low-priority (transitional)
  • isPending: a boolean indicating when the transition is in progress, perfect for showing a loader

Core Example: Updating a Profile

import React, { useState, useTransition } from "react";

function App() {
  const [name, setName] = useState("");
  const [message, setMessage] = useState("");
  const [isPending, startTransition] = useTransition();

  function updateName(newName) {
    // Simulate an async API call
    return new Promise((resolve) => {
      setTimeout(() => {
        if (newName.trim() === "") {
          resolve("Name cannot be empty");
        } else {
          resolve(null);
        }
      }, 1500);
    });
  }

  const handleSubmit = () => {
    setMessage(""); // clear old message
    startTransition(async () => {
      const error = await updateName(name);
      if (error) {
        setMessage(error);
        return;
      }
      setMessage(`✅ Name saved: ${name}`);
    });
  };

  return (
    <div style={{ padding: "2rem", fontFamily: "sans-serif" }}>
      <h2>React 19 – useTransition Demo</h2>
      <input
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="Enter your name"
        style={{ padding: "0.5rem", marginRight: "0.5rem" }}
      />
      <button onClick={handleSubmit} disabled={isPending}>
        {isPending ? "Saving..." : "Save"}
      </button>
      {message && <p>{message}</p>}
    </div>
  );
}

export default App;

Enter fullscreen mode Exit fullscreen mode

How it works:

  1. As soon as startTransition is called, isPending becomes true → you can disable the button and show a “Saving…” state.
  2. The async logic runs inside the transition.
  3. Once complete, isPending returns to false, and the UI responds accordingly.

What Makes This Cleaner Than Before?

Before React 19, you’d manage isPending, error, and redirection manually via useState. Now, useTransition wraps it all smartly, letting you focus on what matters—just the logic, without UI stutter.


Wrap-Up & React 19 Context

  • In React 19, useTransition now supports async logic inside transitions, simplifying UX patterns like pending states, error handling, and optimistic updates.
  • These improvements reduce boilerplate and elevate app responsiveness.

Top comments (0)