[REF] improve children handling in components/fibers

This commit is contained in:
Géry Debongnie
2022-03-30 16:10:04 +02:00
committed by Samuel Degueldre
parent 9b93521da4
commit 989b0d6709
3 changed files with 21 additions and 28 deletions
+4 -18
View File
@@ -116,9 +116,10 @@ export function component<P extends object>(
}
node = new ComponentNode(C, props, ctx.app, ctx);
ctx.children[key] = node;
node.initiateRender(new Fiber(node, parentFiber));
}
parentFiber.childrenMap[key] = node;
parentFiber.root!.reachedChildren.add(node);
return node;
}
@@ -326,6 +327,7 @@ export class ComponentNode<P extends object = any, E = any> implements VNode<Com
bdom.mount(parent, anchor);
this.status = STATUS.MOUNTED;
this.fiber!.appliedToDom = true;
this.children = this.fiber!.childrenMap;
this.fiber = null;
}
@@ -343,10 +345,8 @@ export class ComponentNode<P extends object = any, E = any> implements VNode<Com
}
_patch() {
const hasChildren = Object.keys(this.children).length > 0;
this.children = this.fiber!.childrenMap;
this.bdom!.patch(this!.fiber!.bdom!, hasChildren);
if (hasChildren) {
this.cleanOutdatedChildren();
}
this.fiber!.appliedToDom = true;
this.fiber = null;
}
@@ -359,20 +359,6 @@ export class ComponentNode<P extends object = any, E = any> implements VNode<Com
this.bdom!.remove();
}
cleanOutdatedChildren() {
const children = this.children;
for (const key in children) {
const node = children[key];
const status = node.status;
if (status !== STATUS.MOUNTED) {
delete children[key];
if (status !== STATUS.DESTROYED) {
node.destroy();
}
}
}
}
// ---------------------------------------------------------------------------
// Some debug helpers
// ---------------------------------------------------------------------------
+9 -2
View File
@@ -18,6 +18,7 @@ export function makeRootFiber(node: ComponentNode): Fiber {
let root = current.root!;
root.setCounter(root.counter + 1 - cancelFibers(current.children));
current.children = [];
current.childrenMap = {};
current.bdom = null;
if (current === root) {
root.reachedChildren = new WeakSet();
@@ -45,7 +46,11 @@ export function makeRootFiber(node: ComponentNode): Fiber {
function cancelFibers(fibers: Fiber[]): number {
let result = 0;
for (let fiber of fibers) {
fiber.node.fiber = null;
let node = fiber.node;
if (node.status === STATUS.NEW) {
node.destroy();
}
node.fiber = null;
if (fiber.bdom) {
// if fiber has been rendered, this means that the component props have
// been updated. however, this fiber will not be patched to the dom, so
@@ -53,7 +58,7 @@ function cancelFibers(fibers: Fiber[]): number {
// the same props, and skip the render completely. With the next line,
// we kindly request the component code to force a render, so it works as
// expected.
fiber.node.forceNextRender = true;
node.forceNextRender = true;
} else {
result++;
}
@@ -70,6 +75,7 @@ export class Fiber {
children: Fiber[] = [];
appliedToDom = false;
deep: boolean = false;
childrenMap: ComponentNode["children"] = {};
constructor(node: ComponentNode, parent: Fiber | null) {
this.node = node;
@@ -218,6 +224,7 @@ export class MountFiber extends RootFiber {
let current: Fiber | undefined = this;
try {
const node = this.node;
node.children = this.childrenMap;
(node.app.constructor as any).validateTarget(this.target);
if (node.bdom) {
// this is a complicated situation: if we mount a fiber with an existing