You have a view that renders like this.
<MyComponent />
Now, if this view was to be re-rendered multiple times (leading to the same state/lifecycle, or what you call a transfer, which is not quite the word I'd use, between each render), then the below conditions are true.
- Is it the same component type (the tag name:
<MyComponent />
) in this render tree as the last one?
- Is the component in the same place as last time, same parent etc?
- If the component had a key attribute assigned to it in the last render, is it in the next render tree under the same parent as last time, with the same key value?
Imagine a complete render tree in below pseudo code:
<div id="awesome-container">
<Parent>
{ randomBoolean ? <AlphaChild /> : <BetaChild /> }
</Parent>
</div>
Alpha and Beta components will always unmount when they get replaced with another one, and their state will be "reset", aka they will get mounted as new components.
Looking at the above example, you may think of it all as "unresolved HTML". The custom tags are not the final product of what's in the DOM. Instead, when resolved, it looks more like this:
<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>
If AlphaChild
was suddenly replaced with BetaChild
, there'd be no point to keep the AlphaChild
state/lifecycle around, right? And if we did want to keep it around, we are likely keeping some data which is way too important for a mere child in a list to maintain (A smart component / parent, or Redux, comes to mind). You could always just hide the component too using CSS, just to preserve the state.
And if we didn't have keys, we wouldn't be able to switch the components around.
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 }
}
Whatever order the components above resulted in, for example:
<BetaChild /> // has state
<AlphaChild /> // has state
<CharlieChild /> // has state
The state would be killed off between each re-ordering of the components.
<AlphaChild /> // has completely new state
<CharlieChild /> // has completely new state
<BetaChild /> // has completely new state
That's why keys are very important in react, to keep state in a list that is very likely to be re-ordered.
There isn't much more than that to keep track of. If a component gets removed from its parent and appears somewhere else in the code, it will not keep its old state/lifecycle because it is far from obvious that they are the same. In fact, there's no logical way that tells us that is the case. Not even with keys, because keys can be part of any multiple lists in the rendering process.
I hope this makes things a tad more clear. If you want to learn more about virtual DOM, I suggest checking out Snabbdom on github. They don't keep component lifecycles for you, so you'd need to figure it out yourself. Snabbmitt could be useful to check out for inspirational purposes.
Generally though, I think you don't need to bother too much reading about the virtual DOM, just follow the principles and you should be OK.