重新呈现后VDOM中有状态组件的位置

时间:2017-05-26 14:48:08

标签: reactjs virtual-dom

如果有状态的反应组件CP

的VDOM V中位于T位置

然后

重新渲染后,CV'时会在{​​{1}}的哪个位置?

例如,在this中,第一个有状态组件的状态是"转移"当父道具从T+1更改为true时,到第二个有状态组件。切换回时,第二个组件的状态也会丢失。怎么解释这个?记录此行为的规则是否可用于某处? Here没有非常准确地描述它。

1 个答案:

答案 0 :(得分:1)

你有一个像这样呈现的视图。

<MyComponent />

现在,如果要多次重新渲染此视图(导致相同的状态/生命周期,或者您所谓的传输,这不是我使用的词,在每个渲染之间),则以下条件为真。

  • 此渲染树中的组件类型(标记名称:<MyComponent />)是否为最后一个?
  • 组件与上次相同位置,同一父母等?
  • 如果组件在最后一次渲染中为其分配了一个键属性,它是否在与上次相同的父级下的下一个渲染树中,具有相同的键值?

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

<div id="awesome-container">
    <Parent>
        { randomBoolean ? <AlphaChild /> : <BetaChild /> }
    </Parent>
</div>
当Alpha和Beta组件被另一个组件替换时,它们将始终卸载,并且它们的状态将被“重置”,也就是说它们将挂载作为新组件。

查看上面的示例,您可能会将其视为“未解析的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州/生命周期,对吗?如果我们确实希望保留它,我们可能会保留一些数据,这对于列表中的纯粹孩子来说太重要了(想到一个智能组件/父级或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

在每次重新排序组件之间,状态将被终止。

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

这就是为什么键在反应中非常重要,以便将状态保存在很可能被重新排序的列表中。

没有比追踪更多的东西了。如果一个组件从其父组件中删除并出现在代码中的其他位置,它将保持其旧的状态/生命周期,因为它们是相同的并不明显。事实上,没有合乎逻辑的方式告诉我们情况就是这样。甚至没有键,因为键可以是渲染过程中任何多个列表的一部分。

我希望这会让事情变得更加明确。如果您想了解有关虚拟DOM的更多信息,建议您查看Snabbdom on github。它们不会为您保留组件生命周期,因此您需要自己弄清楚它。 Snabbmitt可能有助于查看鼓舞人心的目的。

一般来说,我认为你不需要太多关于虚拟DOM的阅读,只要按照原则进行操作就应该没问题。