@samitouri / QOS-React-2 / commits / 1376048bd9

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".

Sebastian Markbage committed Oct 24, 2016 at 12:06 UTC 1376048bd9f4b87882304296faeec54acea5717a
2 files changed +18 -3
src/renderers/shared/fiber/ReactFiberCommitWork.js
+15 -3
@@ -186,13 +186,14 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
186 // Recursively delete all host nodes from the parent.
187 // TODO: Error handling.
188 const parent = getHostParent(current);
189 +
190 // We only have the top Fiber that was inserted but we need recurse down its
191 // children to find all the terminal nodes.
192 // TODO: Call componentWillUnmount on all classes as needed. Recurse down
193 // removed HostComponents but don't call removeChild on already removed
194 // children.
195 let node : Fiber = current;
195 - while (true) {
196 + outer: while (true) {
197 if (node.tag === HostComponent || node.tag === HostText) {
198 commitNestedUnmounts(node);
199 // 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>) {
210 }
211 }
212 if (node === current) {
212 - return;
213 + break outer;
214 }
215 while (!node.sibling) {
216 if (!node.return || node.return === current) {
216 - return;
217 + break outer;
218 }
219 node = node.return;
220 }
221 node = node.sibling;
222 }
223 + // Cut off the return pointers to disconnect it from the tree. Ideally, we
224 + // should clear the child pointer of the parent alternate to let this
225 + // get GC:ed but we don't know which for sure which parent is the current
226 + // one so we'll settle for GC:ing the subtree of this child. This child
227 + // itself will be GC:ed when the parent updates the next time.
228 + current.return = null;
229 + current.child = null;
230 + if (current.alternate) {
231 + current.alternate.child = null;
232 + current.alternate.return = null;
233 + }
234 }
235
236 function commitUnmount(current : Fiber) : void {
src/renderers/shared/fiber/ReactFiberScheduler.js
+3
@@ -156,6 +156,9 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
156 // and lastEffect since they're on every node, not just the effectful
157 // ones. So we have to clean everything as we reuse nodes anyway.
158 effectfulFiber.nextEffect = null;
159 + // Ensure that we reset the effectTag here so that we can rely on effect
160 + // tags to reason about the current life-cycle.
161 + effectfulFiber.effectTag = NoWork;
162 effectfulFiber = next;
163 }
164