diff --git a/demo/index.html b/demo/index.html index 670bceb0..248e6734 100644 --- a/demo/index.html +++ b/demo/index.html @@ -10,7 +10,7 @@
- + \ No newline at end of file diff --git a/src/reconciler.ts b/src/reconciler.ts index d52c90c0..117dcd7b 100644 --- a/src/reconciler.ts +++ b/src/reconciler.ts @@ -7,7 +7,6 @@ import { isArr, createText } from './h' let preCommit: IFiber | undefined let currentFiber: IFiber let WIP: IFiber | undefined -let commits: IFiber[] = [] let deletes = [] const microTask: IFiber[] = [] @@ -46,7 +45,6 @@ const reconcileWork = (timeout: boolean): boolean => { const reconcile = (WIP: IFiber): IFiber | undefined => { isFn(WIP.type) ? updateHook(WIP) : updateHost(WIP) WIP.dirty = WIP.dirty ? false : 0 - WIP.parent && commits.push(WIP) if (WIP.child) return WIP.child while (WIP) { @@ -179,10 +177,9 @@ function clone(a, b) { const getKey = (vdom) => (vdom == null ? vdom : vdom.key) const commitWork = (fiber: IFiber): void => { - commits.forEach(commit) + fiber.parent ? commit(fiber) : commit(fiber.child) deletes.forEach(commit) fiber.done?.() - commits = [] deletes = [] preCommit = null WIP = null @@ -200,8 +197,9 @@ const getChild = (WIP: IFiber): any => { } const commit = (fiber: IFiber): void => { - let { tag, parentNode, node, ref, hooks } = fiber - if (isFn(fiber.type)) { + if (!fiber) return + let { type,tag, parentNode, node, ref, hooks } = fiber + if (isFn(type)) { const realChild = getChild(fiber) if (fiber.tag & OP.REMOVE) { commit(realChild) @@ -209,31 +207,31 @@ const commit = (fiber: IFiber): void => { } else { fiber.node = realChild.node if (hooks) { - side(fiber.hooks.layout) - schedule(() => side(fiber.hooks.effect)) + side(hooks.layout) + schedule(() => side(hooks.effect)) } + commit(fiber.child) + commit(fiber.sibling) } return } - if (tag & OP.UPDATE) { - updateElement(node, fiber.lastProps || {}, fiber.props) - } if (tag & OP.REMOVE) { - node = null - cleanupRef(fiber.kids) + kidsRefer(fiber.kids) parentNode.removeChild(fiber.node) + refer(ref, null) + return + } + if (tag & OP.UPDATE) { + updateElement(node, fiber.lastProps || {}, fiber.props) } if (tag & OP.INSERT) { const after = fiber.insertPoint as any - if (after === fiber.node) return if (after === null && fiber.node === parentNode.lastChild) return parentNode.insertBefore(fiber.node, after) } refer(ref, node) -} - -function isChild(p, c) { - return Array.from(p.childNodes).some((i) => c == i) + commit(fiber.child) + commit(fiber.sibling) } const same = (a, b) => a.type === b.type && getKey(a) === getKey(b) @@ -244,10 +242,10 @@ const refer = (ref: IRef, dom?: HTMLElement): void => { if (ref) isFn(ref) ? ref(dom) : ((ref as { current?: HTMLElement })!.current = dom) } -const cleanupRef = (kids: any): void => { +const kidsRefer = (kids: any): void => { kids.forEach((kid) => { refer(kid.ref, null) - kid.kids && cleanupRef(kid.kids) + kid.kids && kidsRefer(kid.kids) }) }