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