Revert "[REF] improve children handling in components/fibers"

This reverts commit 989b0d6709.
This commit is contained in:
Géry Debongnie
2022-03-31 14:28:41 +02:00
parent 989b0d6709
commit 4cd1df46b3
3 changed files with 28 additions and 21 deletions
+18 -4
View File
@@ -116,10 +116,9 @@ export function component<P extends object>(
} }
node = new ComponentNode(C, props, ctx.app, ctx); node = new ComponentNode(C, props, ctx.app, ctx);
ctx.children[key] = node; ctx.children[key] = node;
node.initiateRender(new Fiber(node, parentFiber)); node.initiateRender(new Fiber(node, parentFiber));
} }
parentFiber.childrenMap[key] = node;
parentFiber.root!.reachedChildren.add(node); parentFiber.root!.reachedChildren.add(node);
return node; return node;
} }
@@ -327,7 +326,6 @@ export class ComponentNode<P extends object = any, E = any> implements VNode<Com
bdom.mount(parent, anchor); bdom.mount(parent, anchor);
this.status = STATUS.MOUNTED; this.status = STATUS.MOUNTED;
this.fiber!.appliedToDom = true; this.fiber!.appliedToDom = true;
this.children = this.fiber!.childrenMap;
this.fiber = null; this.fiber = null;
} }
@@ -345,8 +343,10 @@ export class ComponentNode<P extends object = any, E = any> implements VNode<Com
} }
_patch() { _patch() {
const hasChildren = Object.keys(this.children).length > 0; const hasChildren = Object.keys(this.children).length > 0;
this.children = this.fiber!.childrenMap;
this.bdom!.patch(this!.fiber!.bdom!, hasChildren); this.bdom!.patch(this!.fiber!.bdom!, hasChildren);
if (hasChildren) {
this.cleanOutdatedChildren();
}
this.fiber!.appliedToDom = true; this.fiber!.appliedToDom = true;
this.fiber = null; this.fiber = null;
} }
@@ -359,6 +359,20 @@ export class ComponentNode<P extends object = any, E = any> implements VNode<Com
this.bdom!.remove(); 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 // Some debug helpers
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
+2 -9
View File
@@ -18,7 +18,6 @@ export function makeRootFiber(node: ComponentNode): Fiber {
let root = current.root!; let root = current.root!;
root.setCounter(root.counter + 1 - cancelFibers(current.children)); root.setCounter(root.counter + 1 - cancelFibers(current.children));
current.children = []; current.children = [];
current.childrenMap = {};
current.bdom = null; current.bdom = null;
if (current === root) { if (current === root) {
root.reachedChildren = new WeakSet(); root.reachedChildren = new WeakSet();
@@ -46,11 +45,7 @@ export function makeRootFiber(node: ComponentNode): Fiber {
function cancelFibers(fibers: Fiber[]): number { function cancelFibers(fibers: Fiber[]): number {
let result = 0; let result = 0;
for (let fiber of fibers) { for (let fiber of fibers) {
let node = fiber.node; fiber.node.fiber = null;
if (node.status === STATUS.NEW) {
node.destroy();
}
node.fiber = null;
if (fiber.bdom) { if (fiber.bdom) {
// if fiber has been rendered, this means that the component props have // 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 // been updated. however, this fiber will not be patched to the dom, so
@@ -58,7 +53,7 @@ function cancelFibers(fibers: Fiber[]): number {
// the same props, and skip the render completely. With the next line, // 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 // we kindly request the component code to force a render, so it works as
// expected. // expected.
node.forceNextRender = true; fiber.node.forceNextRender = true;
} else { } else {
result++; result++;
} }
@@ -75,7 +70,6 @@ export class Fiber {
children: Fiber[] = []; children: Fiber[] = [];
appliedToDom = false; appliedToDom = false;
deep: boolean = false; deep: boolean = false;
childrenMap: ComponentNode["children"] = {};
constructor(node: ComponentNode, parent: Fiber | null) { constructor(node: ComponentNode, parent: Fiber | null) {
this.node = node; this.node = node;
@@ -224,7 +218,6 @@ export class MountFiber extends RootFiber {
let current: Fiber | undefined = this; let current: Fiber | undefined = this;
try { try {
const node = this.node; const node = this.node;
node.children = this.childrenMap;
(node.app.constructor as any).validateTarget(this.target); (node.app.constructor as any).validateTarget(this.target);
if (node.bdom) { if (node.bdom) {
// this is a complicated situation: if we mount a fiber with an existing // this is a complicated situation: if we mount a fiber with an existing
+8 -8
View File
@@ -114,8 +114,8 @@ test("destroying/recreating a subwidget with different props (if start is not ov
expect(n).toBe(2); expect(n).toBe(2);
expect([ expect([
"Child:willDestroy",
"W:willRender", "W:willRender",
"Child:willDestroy",
"Child:setup", "Child:setup",
"Child:willStart", "Child:willStart",
"W:rendered", "W:rendered",
@@ -244,8 +244,8 @@ test("creating two async components, scenario 1", async () => {
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe(""); expect(fixture.innerHTML).toBe("");
expect([ expect([
"ChildA:willDestroy",
"Parent:willRender", "Parent:willRender",
"ChildA:willDestroy",
"ChildA:setup", "ChildA:setup",
"ChildA:willStart", "ChildA:willStart",
"ChildB:setup", "ChildB:setup",
@@ -696,8 +696,8 @@ test("rendering component again in next microtick", async () => {
"Child:setup", "Child:setup",
"Child:willStart", "Child:willStart",
"Parent:rendered", "Parent:rendered",
"Child:willDestroy",
"Parent:willRender", "Parent:willRender",
"Child:willDestroy",
"Child:setup", "Child:setup",
"Child:willStart", "Child:willStart",
"Parent:rendered", "Parent:rendered",
@@ -1725,7 +1725,6 @@ test("concurrent renderings scenario 10", async () => {
expect(fixture.innerHTML).toBe("<div><p></p></div>"); expect(fixture.innerHTML).toBe("<div><p></p></div>");
expect([ expect([
"ComponentA:willRender", "ComponentA:willRender",
"ComponentC:willDestroy",
"ComponentB:willUpdateProps", "ComponentB:willUpdateProps",
"ComponentA:rendered", "ComponentA:rendered",
]).toBeLogged(); ]).toBeLogged();
@@ -1736,6 +1735,7 @@ test("concurrent renderings scenario 10", async () => {
expect(rendered).toBe(1); expect(rendered).toBe(1);
expect([ expect([
"ComponentB:willRender", "ComponentB:willRender",
"ComponentC:willDestroy",
"ComponentC:setup", "ComponentC:setup",
"ComponentC:willStart", "ComponentC:willStart",
"ComponentB:rendered", "ComponentB:rendered",
@@ -2275,11 +2275,11 @@ test("concurrent renderings scenario 16", async () => {
"D:setup", "D:setup",
"D:willStart", "D:willStart",
"C:rendered", "C:rendered",
"D:willDestroy",
"B:willRender", "B:willRender",
"C:willUpdateProps", "C:willUpdateProps",
"B:rendered", "B:rendered",
"C:willRender", "C:willRender",
"D:willDestroy",
"D:setup", "D:setup",
"D:willStart", "D:willStart",
"C:rendered", "C:rendered",
@@ -2990,13 +2990,13 @@ test("t-key on dom node having a component", async () => {
expect(fixture.innerHTML).toBe("<div>3</div>"); expect(fixture.innerHTML).toBe("<div>3</div>");
expect([ expect([
"Child (2):willDestroy",
"Child (3):setup", "Child (3):setup",
"Child (3):willStart", "Child (3):willStart",
"Child (3):willRender", "Child (3):willRender",
"Child (3):rendered", "Child (3):rendered",
"Child (1):willUnmount", "Child (1):willUnmount",
"Child (1):willDestroy", "Child (1):willDestroy",
"Child (2):willDestroy",
"Child (3):mounted", "Child (3):mounted",
]).toBeLogged(); ]).toBeLogged();
}); });
@@ -3048,13 +3048,13 @@ test("t-key on dynamic async component (toggler is never patched)", async () =>
expect(fixture.innerHTML).toBe("<div>3</div>"); expect(fixture.innerHTML).toBe("<div>3</div>");
expect([ expect([
"Child (2):willDestroy",
"Child (3):setup", "Child (3):setup",
"Child (3):willStart", "Child (3):willStart",
"Child (3):willRender", "Child (3):willRender",
"Child (3):rendered", "Child (3):rendered",
"Child (1):willUnmount", "Child (1):willUnmount",
"Child (1):willDestroy", "Child (1):willDestroy",
"Child (2):willDestroy",
"Child (3):mounted", "Child (3):mounted",
]).toBeLogged(); ]).toBeLogged();
}); });
@@ -3107,13 +3107,13 @@ test("t-foreach with dynamic async component", async () => {
expect(fixture.innerHTML).toBe("<div>3</div>"); expect(fixture.innerHTML).toBe("<div>3</div>");
expect([ expect([
"Child (2):willDestroy",
"Child (3):setup", "Child (3):setup",
"Child (3):willStart", "Child (3):willStart",
"Child (3):willRender", "Child (3):willRender",
"Child (3):rendered", "Child (3):rendered",
"Child (1):willUnmount", "Child (1):willUnmount",
"Child (1):willDestroy", "Child (1):willDestroy",
"Child (2):willDestroy",
"Child (3):mounted", "Child (3):mounted",
]).toBeLogged(); ]).toBeLogged();
}); });