diff --git a/compat/test/browser/suspense-hydration.test.js b/compat/test/browser/suspense-hydration.test.js index 9143903238..b364cf41c6 100644 --- a/compat/test/browser/suspense-hydration.test.js +++ b/compat/test/browser/suspense-hydration.test.js @@ -97,6 +97,30 @@ describe('suspense hydration', () => { }); }); + it('should leave DOM untouched when suspending while hydrating', () => { + scratch.innerHTML = '
Hello
'; + clearLog(); + + const [Lazy, resolve] = createLazy(); + hydrate( + + + , + scratch + ); + rerender(); // Flush rerender queue to mimic what preact will really do + expect(scratch.innerHTML).to.equal('
Hello
'); + expect(getLog()).to.deep.equal([]); + clearLog(); + + return resolve(() =>
Hello
).then(() => { + rerender(); + expect(scratch.innerHTML).to.equal('
Hello
'); + expect(getLog()).to.deep.equal([]); + clearLog(); + }); + }); + it('should properly attach event listeners when suspending while hydrating', () => { scratch.innerHTML = '
Hello
World
'; clearLog(); diff --git a/src/diff/index.js b/src/diff/index.js index 3e4b17bd62..84c801bd02 100644 --- a/src/diff/index.js +++ b/src/diff/index.js @@ -273,13 +273,15 @@ export function diff( newVNode._original = null; // if hydrating or creating initial tree, bailout preserves DOM: if (isHydrating || excessDomChildren != null) { - newVNode._dom = oldDom; newVNode._flags |= isHydrating ? MODE_HYDRATE | MODE_SUSPENDED : MODE_HYDRATE; + + while (oldDom && oldDom.nodeType === 8 && oldDom.nextSibling) { + oldDom = oldDom.nextSibling; + } excessDomChildren[excessDomChildren.indexOf(oldDom)] = null; - // ^ could possibly be simplified to: - // excessDomChildren.length = 0; + newVNode._dom = oldDom; } else { newVNode._dom = oldVNode._dom; newVNode._children = oldVNode._children;