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> ))} </> ) }
修改说明:
- 移除了
useTransition相关代码,直接调用addOptimisticItem,点击按钮后UI会立即显示"optimistic"项。 setItems改用函数式更新prevItems => [...prevItems, 'actual'],确保每次都基于最新的状态添加新项,避免闭包导致的状态丢失问题。- 简化了按钮的
onClick写法,直接传addToList即可。
这样修改后,点击按钮会立刻显示乐观项,两秒后乐观项会被真实的"actual"项替换,完全符合你的预期。
内容的提问来源于stack exchange,提问作者Makazau
相关产品推荐
相关产品推荐

