React19新特性,乐观更新useOptimistic()范例代码优化
发布于 作者:苏南大叔 来源:程序如此灵动~

乐观更新这个事情,其实存在着一些问题。主要体现在“为了乐观更新,就不考虑服务器提交等待”这个问题上。启用了乐观更新的概念后,界面上的各种按钮及输入框,是没有disabled
这种说法的。想想看,这种提交等待的传统做法,是不是和乐观更新的思想冲突呢?短时间内大量提交的话,消息的时间轴存在混乱和重复的问题。

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。本文测试环境:nodejs@20.18.0
,create-react-app@5.0.1
,react@19.0.0
。本文视图解决useOptimistic()
官方范例里面的消息的时间轴重复和混乱的问题。
前文回顾
本文代码的useOptimistic()
范例代码,来自下面的这篇文章。
主要实现的功能就是:面对大概率成功的接口数据交互,提前假设数据正常返回,界面迅速得到渲染,提高用户体验。这个问题,被乱蒿羊毛的结果,就是极短时间内多次触发提交的话。数据混乱和重复的问题。
useTransition()
试图通过useTransition()
来解决上述问题,效果也并不明显。参考文章:
使用useTransition()
,来获得pending
状态和一个可过渡的逻辑包装组合。被useTransition()
包裹的代码端,具有较低的优先级,如果有界面交互用户输入的高优先级任务的时候,这些低优先级的任务会被延迟执行。
考虑到和乐观更新的效果相抵触,代码中并没有对pending
状态进行使用。仅仅保留了formAction
中的startTransition()
。
其实这个useTransition()
效果,并不明显。似乎更多的是出于心理安慰的作用。
增加消息id
这里对每条消息增加了一个key
,其实也可以理解为自增id
。主要想利用这个自增值来确定消息的身份和先后顺序。

解决顺序混乱的问题
顺序为什么会混乱,主要原因在于苏南大叔修改的代码里面,服务器端返回的时间做了随机,这也更贴近现实的情况。如果服务器返回时间都一致的话,消息顺序并不会“混乱”。
解决方案的原理,苏南大叔是利用界面格式化的时候,对"乐观数据"进行了排序(.sort()
)。

解决数据重复的问题
据仔细观察,重复的数据都是瞬时存在的。两条同一个key
的数据,处于两个不同的sending
状态。如果调试useOptimistic()
钩子的第二个参数的话。会发现这个合并数据的逻辑被执行了两次。所以,问题就出在这个“两次”上。
修改完的逻辑如下:

完整代码
完整代码如下:

结语
在本文的代码里面,对于“乐观更新”这个思想,又增加了新的认识。更新可以保持乐观,但是也带来了一定的数据不可靠性。所以,双刃剑。


