概览useOptimistic 可在提交前立即更新 UI,降低交互延迟感。结合撤销与冲突合并策略,在后台确认失败或产生竞态时稳定回滚或合并,保证一致性与可控性。基础用法'use client' import { useOptimistic, useState } from 'react' type Item = { id: string; text: string } export default function List() { const [items, setItems] = useState<Item[]>([]) const [optimisticItems, addOptimistic] = useOptimistic(items, (state, pending: Item) => { return [...state, pending] }) async function add(text: string) { const temp: Item = { id: crypto.randomUUID(), text } addOptimistic(temp) const ok = await submit(temp) if (!ok) { setItems((prev) => prev.filter((i) => i.id !== temp.id)) } else { setItems((prev) => [...prev, temp]) } } return ( <div> <button onClick={() => add('任务')}>添加</button> <ul> {optimisticItems.map((i) => ( <li key={i.id}>{i.text}</li> ))} </ul> </div> ) } async function submit(i: Item) { await new Promise((r) => setTimeout(r, 400)) return Math.random() > 0.2 } 撤销与冲突合并'use client' import { useOptimistic, useRef, useState } from 'react' type Change = { id: string; text: string } export function Editor() { const [base, setBase] = useState<string>('') const [optimistic, apply] = useOptimistic(base, (state, change: Change) => change.text) const queue = useRef<Change[]>([]) async function save(next: string) { const change: Change = { id: crypto.randomUUID(), text: next } apply(change) queue.current.push(change) const ok = await commit(change) if (!ok) { // 合并策略:回退到最新成功版本 const last = queue.current.at(-2) setBase(last ? last.text : base) } else { setBase(next) } } return ( <div> <textarea defaultValue={base} onBlur={(e) => save(e.target.value)} /> <p>预览:{optimistic}</p> </div> ) } async function commit(c: Change) { await new Promise((r) => setTimeout(r, 500)) return true } 治理要点对失败场景提供撤销或回滚保障,避免状态撕裂。合并策略以最新成功提交为基线,减少竞态污染。与 Server Actions 协作,将幂等与去重纳入后端保障。验证与指标React:19.0+;Next.js:15.0+即时反馈:按钮与文本在 100–200ms 内出现乐观更新;失败可在 1s 内回滚

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部
2.015610s