From 0e691f2bc95ec850957a4858544e0eea5f6f1a90 Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Sat, 2 Mar 2024 07:38:01 +0100 Subject: [PATCH] Revert "Merge pull request #4234 from preactjs/multi-root-shared-commit" This reverts commit f7ccb9010077ecb46fc271224bbc5e015e00efe6, reversing changes made to e1f0d3e626d6ebc76a2851e830c5b6020c353cf2. --- .../test/browser/useSyncExternalStore.test.js | 5 +++- src/component.js | 29 +++++-------------- src/diff/index.js | 2 ++ src/render.js | 2 +- 4 files changed, 15 insertions(+), 23 deletions(-) diff --git a/compat/test/browser/useSyncExternalStore.test.js b/compat/test/browser/useSyncExternalStore.test.js index c51760cd24..2f5ab16a03 100644 --- a/compat/test/browser/useSyncExternalStore.test.js +++ b/compat/test/browser/useSyncExternalStore.test.js @@ -658,7 +658,10 @@ describe('useSyncExternalStore', () => { await act(() => { store.set(1); }); - assertLog([1, 1, 'Reset back to 0', 0, 0]); + // Preact logs differ from React here cuz of how we do rerendering. We + // rerender subtrees and then commit effects so Child2 never sees the + // update to 1 cuz Child1 rerenders and runs its layout effects first. + assertLog([1, /*1,*/ 'Reset back to 0', 0, 0]); expect(container.textContent).to.equal('00'); }); diff --git a/src/component.js b/src/component.js index d38f60ca36..62b2439f72 100644 --- a/src/component.js +++ b/src/component.js @@ -2,7 +2,7 @@ import { assign } from './util'; import { diff, commitRoot } from './diff/index'; import options from './options'; import { Fragment } from './create-element'; -import { EMPTY_ARR, MODE_HYDRATE } from './constants'; +import { MODE_HYDRATE } from './constants'; /** * Base Component class. Provides `setState()` and `forceUpdate()`, which @@ -120,10 +120,12 @@ export function getDomSibling(vnode, childIndex) { * Trigger in-place re-rendering of a component. * @param {Component} component The component to rerender */ -function renderComponent(component, commitQueue, refQueue) { +function renderComponent(component) { let oldVNode = component._vnode, oldDom = oldVNode._dom, - parentDom = component._parentDom; + parentDom = component._parentDom, + commitQueue = [], + refQueue = []; if (parentDom) { const newVNode = assign({}, oldVNode); @@ -145,14 +147,11 @@ function renderComponent(component, commitQueue, refQueue) { newVNode._original = oldVNode._original; newVNode._parent._children[newVNode._index] = newVNode; - - newVNode._nextDom = undefined; + commitRoot(commitQueue, newVNode, refQueue); if (newVNode._dom != oldDom) { updateParentDomPointers(newVNode); } - - return newVNode; } } @@ -222,33 +221,21 @@ const depthSort = (a, b) => a._vnode._depth - b._vnode._depth; /** Flush the render queue by rerendering all queued components */ function process() { let c; - let commitQueue = []; - let refQueue = []; - let root; rerenderQueue.sort(depthSort); // Don't update `renderCount` yet. Keep its value non-zero to prevent unnecessary // process() calls from getting scheduled while `queue` is still being consumed. while ((c = rerenderQueue.shift())) { if (c._dirty) { let renderQueueLength = rerenderQueue.length; - root = renderComponent(c, commitQueue, refQueue) || root; - // If this WAS the last component in the queue, run commit callbacks *before* we exit the tight loop. - // This is required in order for `componentDidMount(){this.setState()}` to be batched into one flush. - // Otherwise, also run commit callbacks if the render queue was mutated. - if (renderQueueLength === 0 || rerenderQueue.length > renderQueueLength) { - commitRoot(commitQueue, root, refQueue); - refQueue.length = commitQueue.length = 0; - root = undefined; + renderComponent(c); + if (rerenderQueue.length > renderQueueLength) { // When i.e. rerendering a provider additional new items can be injected, we want to // keep the order from top to bottom with those new items so we can handle them in a // single pass rerenderQueue.sort(depthSort); - } else if (root) { - if (options._commit) options._commit(root, EMPTY_ARR); } } } - if (root) commitRoot(commitQueue, root, refQueue); process._rerenderCount = 0; } diff --git a/src/diff/index.js b/src/diff/index.js index 16b07395a2..b5bbb49db6 100644 --- a/src/diff/index.js +++ b/src/diff/index.js @@ -311,6 +311,8 @@ export function diff( * @param {VNode} root */ export function commitRoot(commitQueue, root, refQueue) { + root._nextDom = undefined; + for (let i = 0; i < refQueue.length; i++) { applyRef(refQueue[i], refQueue[++i], refQueue[++i]); } diff --git a/src/render.js b/src/render.js index b550ef96af..1ee326bc92 100644 --- a/src/render.js +++ b/src/render.js @@ -59,7 +59,7 @@ export function render(vnode, parentDom, replaceNode) { refQueue ); - vnode._nextDom = undefined; + // Flush all queued effects commitRoot(commitQueue, vnode, refQueue); }