React组件UI树位置变更后状态未重置的原因咨询
为什么隐藏第一个Counter时第二个的状态不会重置?
核心原因是:React判断组件是否复用状态,看的是组件在React元素树中的身份,而非DOM里的视觉位置。这个身份由「组件类型 + 它在父组件子节点列表中的匹配逻辑」共同决定,不是简单的“位置顺序”。
具体拆解你的场景:
当showA为true时,App的子元素结构是:
div ├─ Counter(第1个子节点,索引0) ├─ Counter(第2个子节点,索引1) └─ label(第3个子节点,索引2)
当你取消勾选,showA变为false,结构变成:
div ├─ Counter(第1个子节点,索引0) └─ label(第2个子节点,索引1)
React在对比新旧元素树时,会按顺序匹配同类型的节点:
- 新树里的第一个
Counter,会和旧树里的第二个Counter匹配——因为两者都是Counter类型,React会认为“只是前面的节点被删掉了,这个节点还是原来那个”,所以直接复用旧的组件实例,状态自然保留。 - 而当你重新勾选显示第一个
Counter时,新树里的第一个Counter是全新的节点(旧树里这个位置没有Counter),React会创建新的组件实例,状态也就重置了。
简单总结:React不会因为前面的节点消失,就把后面的同类型节点当成新组件。只有当某个位置第一次出现某类型组件时,才会初始化状态;后续只要能匹配到旧的同类型节点,就会复用状态。
内容的提问来源于stack exchange,提问作者chadibassily
相关产品推荐
相关产品推荐

