You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React useOptimistic未即时更新?如何实现正确乐观更新

修复useOptimistic乐观更新不立即生效的问题

你的代码问题主要出在两个地方:

  • 用startTransition包裹addOptimisticItem:startTransition会把内部的更新标记为非紧急渲染,导致乐观项不会立即显示,反而要等真实请求完成后才短暂出现。乐观更新本身就是要立即生效的,不需要用startTransition包裹。
  • addToDatabase里的状态更新用了快照值:setItems([...items, 'actual'])里的items是组件初始渲染时的快照,不是最新状态,多次点击会丢失之前的更新,得用函数式更新获取最新状态。

修改后的代码如下:

'use client'

import { useOptimistic, useState } from "react"

export default function Home() {
  const [items, setItems] = useState<string[]>([])
  const [optimisticItems, addOptimisticItem] = useOptimistic(
    items,
    (previous: string[], newItem: string) => {
      return [...previous, newItem]
  })

  const addToList = () => {
    // 直接调用addOptimisticItem,立即触发乐观更新
    addOptimisticItem('optimistic')
    setTimeout(() => {addToDatabase()}, 2000)
  }

  const addToDatabase = () => {
    // 用函数式更新获取最新的items状态
    setItems(prevItems => [...prevItems, 'actual'])
  }

  return (
    <>
      <button onClick={addToList}>Add item</button>
      {optimisticItems.map((item, index) => (
        <div key={index}>{item}</div>
      ))}
    </>
  )
}

修改说明:

  1. 移除了useTransition相关代码,直接调用addOptimisticItem,点击按钮后UI会立即显示"optimistic"项。
  2. setItems改用函数式更新prevItems => [...prevItems, 'actual'],确保每次都基于最新的状态添加新项,避免闭包导致的状态丢失问题。
  3. 简化了按钮的onClick写法,直接传addToList即可。

这样修改后,点击按钮会立刻显示乐观项,两秒后乐观项会被真实的"actual"项替换,完全符合你的预期。

内容的提问来源于stack exchange,提问作者Makazau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:27:44