如何理解React在相同位置渲染相同组件时保留状态?
React 组件状态保留与重置的逻辑解析
我在阅读React官方文档的「状态的保留与重置」章节时,对React会在相同位置渲染相同组件时一直保留其状态这个概念存在疑问,尤其是不同位置渲染组件时的表现差异,希望能得到清晰的解释。
同一位置的示例解析
你给出的同一位置代码示例:
{isPlayerA ? ( <Counter person="Taylor" /> ) : ( <Counter person="Sarah" /> )}
这里两个Counter组件始终处于虚拟DOM树的同一个位置——也就是这个三元表达式所在的层级节点。React判断组件实例是否复用状态时,核心看两个点:组件类型(都是Counter),以及它在虚拟DOM树中的位置。所以不管isPlayerA怎么切换,React都会认为这是同一个组件实例,只会更新person属性,之前的计数状态会被保留下来。
不同位置的示例解析(对应你提供的图片内容)
假设图片中的代码结构是类似这样的两个独立条件渲染块:
{isPlayerA && <Counter person="Taylor" />} {!isPlayerA && <Counter person="Sarah" />}
这时候两个Counter处于虚拟DOM树的不同位置——第一个在第一个条件分支的节点位置,第二个在第二个分支的节点位置。
这种情况下切换isPlayerA时,React会先卸载第一个位置的Counter组件(同时销毁它的状态),然后在第二个位置挂载一个全新的Counter实例,自然会初始化新的状态,两个组件的状态完全独立。
核心逻辑总结
React判断组件实例身份的依据是「组件类型 + 虚拟DOM树中的位置」,和组件的props无关:
- 同一位置的同类型组件:被视为同一个实例,状态会被保留复用
- 不同位置的同类型组件:被视为不同实例,状态各自独立,切换时会重置
如果想在同一位置也能重置状态,可以给组件添加唯一的key属性,比如:
{isPlayerA ? ( <Counter key="taylor" person="Taylor" /> ) : ( <Counter key="sarah" person="Sarah" /> )}
key会被React纳入实例身份的判断依据,不同的key会被当作不同的组件实例,切换时就会重置状态。
内容的提问来源于stack exchange,提问作者Alice
相关产品推荐
相关产品推荐

