为何React中用State能更新状态,用Ref却无法实现?
为何用Ref和State处理Props变化的行为不同?
核心差异源于React的渲染机制与State/Ref的本质区别
1. 使用State的写法为何能正常工作?
prevValue是组件的状态变量,它在每次渲染时都是一个不可变的快照:
- 当props的
value变化时,组件触发重新渲染,此时prevValue还保持着旧值,满足value !== prevValue条件,执行setPrevValue和setOtherState。 - React会将这两次状态更新合并,触发一次新的渲染。在新渲染中,
prevValue已经更新为新的value,不会重复进入if分支;而otherState的新值会被正确应用到DOM,所以你能看到内容变化。
这种写法符合React的状态更新逻辑,是官方推荐的模式,逻辑可预测,不会触发额外的渲染问题。
2. 使用Ref的写法为何失效?
valueRef.current是一个可变的引用对象,它的修改不会触发渲染,但在渲染期间同步修改ref后调用setState,会触发React的特殊处理逻辑:
- 当props的
value变化触发渲染时,valueRef.current还是旧值,进入if分支后先同步修改ref的值,再调用setOtherState。 - 这里的问题是:你在组件的渲染阶段(函数执行过程中)直接修改ref并调用状态更新。React不推荐这种写法,因为这会导致不可预测的行为:
- React在渲染期间遇到状态更新时,会触发一次额外的渲染,但此时
valueRef.current已经被同步为新值,第二次渲染时不会进入if分支。 - 在开发环境的严格模式下,React会对这种"渲染期间的状态更新"进行额外校验,可能导致状态更新被忽略或抵消,最终
otherState的变化无法反映到DOM上。
- React在渲染期间遇到状态更新时,会触发一次额外的渲染,但此时
简单来说,Ref的设计是用来存储不需要触发渲染的可变值,而不是用来处理需要同步到状态的props变化——这种场景下State的快照特性才是正确的选择。
内容的提问来源于stack exchange,提问作者Arkellys
相关产品推荐
相关产品推荐

