Clear effectTag and return pointers after side-effects

This will let us use these pointers to reason about a tree.
Whether if it is "current" or "work in progress".
This commit is contained in:
Sebastian Markbage
2016-10-25 13:59:33 -07:00
parent 4de7a775d3
commit ad02fee721
2 changed files with 18 additions and 3 deletions
@@ -186,13 +186,14 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
// Recursively delete all host nodes from the parent.
// TODO: Error handling.
const parent = getHostParent(current);
// We only have the top Fiber that was inserted but we need recurse down its
// children to find all the terminal nodes.
// TODO: Call componentWillUnmount on all classes as needed. Recurse down
// removed HostComponents but don't call removeChild on already removed
// children.
let node : Fiber = current;
while (true) {
outer: while (true) {
if (node.tag === HostComponent || node.tag === HostText) {
commitNestedUnmounts(node);
// After all the children have unmounted, it is now safe to remove the
@@ -209,16 +210,27 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
}
}
if (node === current) {
return;
break outer;
}
while (!node.sibling) {
if (!node.return || node.return === current) {
return;
break outer;
}
node = node.return;
}
node = node.sibling;
}
// Cut off the return pointers to disconnect it from the tree. Ideally, we
// should clear the child pointer of the parent alternate to let this
// get GC:ed but we don't know which for sure which parent is the current
// one so we'll settle for GC:ing the subtree of this child. This child
// itself will be GC:ed when the parent updates the next time.
current.return = null;
current.child = null;
if (current.alternate) {
current.alternate.child = null;
current.alternate.return = null;
}
}
function commitUnmount(current : Fiber) : void {
@@ -156,6 +156,9 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
// and lastEffect since they're on every node, not just the effectful
// ones. So we have to clean everything as we reuse nodes anyway.
effectfulFiber.nextEffect = null;
// Ensure that we reset the effectTag here so that we can rely on effect
// tags to reason about the current life-cycle.
effectfulFiber.effectTag = NoWork;
effectfulFiber = next;
}