useTransition 与 useOptimistic

发布: (2025年12月8日 GMT+8 19:00)
4 min read
原文: Dev.to

Source: Dev.to

Cover image for useTransition vs. useOptimistic

动态二人组:管理过程 vs. 管理感知

要实现“速度幻觉”,你需要两种不同的工具:

  • useTransition – 处理后台工作。它防止浏览器卡死,并告诉你是否有工作在进行(isPending)。
  • useOptimistic – 处理即时视觉反馈。它立即更新 UI,假设后台工作会成功。

场景示例:“点赞”按钮

想象用户点击文章的“点赞”按钮。

  • 没有乐观 UI:
    用户点击 → 等待 1 秒 → 数字上升。(感觉迟缓)。

  • 有乐观 UI:
    用户点击 → 数字立即上升 → 服务器在后台同步。(感觉流畅)。

标准做法(仅 useTransition)

这里我们依赖服务器返回新的点赞数。useTransition 只用于显示加载指示,让用户知道有操作在进行。

体验: 用户点击 → 出现加载指示 → 加载指示消失并更新数字。

'use client';
import { useTransition } from 'react';
import { incrementLike } from './actions'; // Server Action

export default function StandardLikeButton({ likeCount }) {
  const [isPending, startTransition] = useTransition();

  const handleClick = () => {
    startTransition(async () => {
      // 1. Wait for the server to finish
      await incrementLike();
      // 2. UI updates after the server responds and the page re‑renders
    });
  };

  return (
    {/* Show a loading state because we don't have the new data yet */}
    {isPending ? 'Updating...' : `♥ ${likeCount} Likes`}
  );
}

幻觉做法(useTransition + useOptimistic)

我们预测未来。UI 立即更新,而服务器请求在后台运行。useTransition 保持应用响应;useOptimistic 提供即时的视觉变化。

体验: 用户点击 → 数字立即更新(不需要加载指示)。

'use client';
import { useOptimistic, useTransition } from 'react';
import { incrementLike } from './actions';

export default function OptimisticLikeButton({ likeCount }) {
  // Optimistic state: real data + reducer to calculate the "fake" new state
  const [optimisticLikes, addOptimisticLike] = useOptimistic(
    likeCount,
    (currentState, optimisticValue) => currentState + optimisticValue
  );

  const [isPending, startTransition] = useTransition();

  const handleClick = () => {
    startTransition(async () => {
      // 1. ILLUSION: Update the UI immediately
      addOptimisticLike(1);

      // 2. REALITY: Perform the actual server request in the background
      // If this fails, React automatically rolls back the optimistic state!
      await incrementLike();
    });
  };

  return (
    {/* Display the optimistic (predicted) value immediately */}
    ♥ {optimisticLikes} Likes
  );
}

关键差异概览

功能useTransitionuseOptimistic
主要目标防止 UI 冻结;跟踪“加载”状态在服务器确认前立即显示结果
用户体验“请稍等…”(真实的延迟)“完成!”(即时满足)
数据来源等待服务器返回的数据客户端预测
服务器失败时应用保持在之前状态或显示错误UI 会自动回滚到正确的服务器状态

为什么要一起使用?

useOptimistic 在没有 useTransition(或包装了 transition 的 Server Actions)时几乎没有意义。

  • useOptimistic 处理数据(例如显示 101 个赞而不是 100)。
  • useTransition 处理执行(确保按钮点击时页面不会卡死,直到请求发送到服务器)。

两者结合,能够提供快速、流畅的用户体验。

Back to Blog

相关文章

阅读更多 »