重新渲染后有状态组件在 VDOM 中的位置

Location of stateful component in the VDOM after re-render

如果状态反应组件 C 在 VDOM V 中的位置 P 在时间 T

然后

重新渲染后 C 在时间 T+1V' 会在 VDOM 中的什么地方?

例如this fiddle the state of the first stateful component is "transferred" to the second stateful component when the parent prop changes from true to false. Also the second component's state gets lost when switching back. How can this be explained ? Are the rules documenting this behaviour available somewhere ? Here中描述的不是很准确。

您有一个这样呈现的视图。

<MyComponent />

现在,如果此视图要 re-rendered 多次(导致 相同的 state/lifecycle,或者您所说的转移,即不完全是我在每个渲染之间使用的词),则以下条件为真。

  • 这个渲染树中的组件类型(标签名称:<MyComponent />)是否与上一个相同?
  • 组件是否与上次在同一个地方,相同parent等?
  • 如果组件在上次渲染中分配了一个键属性,它是否在与上次相同的 parent 下的下一个渲染树中,具有相同的键值?

在下面的伪代码中想象一个完整的渲染树:

<div id="awesome-container">
    <Parent>
        { randomBoolean ? <AlphaChild /> : <BetaChild /> }
    </Parent>
</div>

Alpha 和 Beta 组件在被另一个组件替换时将始终 卸载,并且它们的状态将为 "reset",也就是它们将获得 安装作为新组件。

看上面的例子,你可能会认为都是"unresolved HTML"。自定义标签不是 DOM 中的最终产品。相反,解决后,它看起来更像这样:

<div id="awesome-container"> // just an element, is stateless
    <div class="parent"> // has a lifecycle/state tied to it
         <span name="alpha"> // also has a lifecycle/state
             <p>My job is to show the time: 10:00 AM</p>
         </span>
    </div>
</div>

如果 AlphaChild 突然被 BetaChild 取代,那 AlphaChild state/lifecycle 就没有意义了,对吧?如果我们确实想保留它,我们可能会保留一些数据,这些数据对于列表中的 child 来说太重要了(智能组件 / parent,或 Redux,来头脑)。您也可以使用 CSS 隐藏组件,只是为了保持状态。

如果我们没有钥匙,我们将无法切换组件。

constructor() {
this.state = { components: [ <AlphaChild />, <BetaChild />, <CharlieChild /> ] };
}

someEvent() {
    // Moves the first element in the array to the last position.
    this.setState({ 
        this.state.components: [this.components.slice(1)].push(this.state.components[0]))
    }
}

render() {
    { this.state.components }
}

无论以上组件的顺序如何,例如:

<BetaChild /> // has state
<AlphaChild /> // has state
<CharlieChild /> // has state

每个 re-ordering 组件之间的状态将被终止。

<AlphaChild /> // has completely new state
<CharlieChild /> // has completely new state
<BetaChild /> // has completely new state

这就是键在 React 中非常重要的原因,可以将状态保存在很可能是 re-ordered 的列表中。

没有比这更多的东西可以跟踪了。如果一个组件从其 parent 中删除并出现在代码中的其他地方,它将 而不是 保留其旧的 state/lifecycle 因为它们远非显而易见相同。事实上,没有任何合乎逻辑的方法可以告诉我们情况是这样的。甚至没有键,因为键可以是渲染过程中任何多个列表的一部分。

我希望这能让事情变得更清楚一点。如果您想了解有关虚拟 DOM 的更多信息,我建议您查看 Snabbdom on github. They don't keep component lifecycles for you, so you'd need to figure it out yourself. Snabbmitt 可能有助于激发灵感。

不过总的来说,我觉得你不需要费心去读太多关于虚拟的东西DOM,只要遵循原则就可以了。