From a108580167e346aa114c431ae0b4d8f9a83e2574 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Mon, 19 Jun 2023 20:31:26 -0400 Subject: [PATCH 1/2] Ensure updates are applied when diffInCommitPhase is on In this case there's no updatePayload. --- .../src/__tests__/ReactDOMFloat-test.js | 21 +++++++++++++++++++ .../src/ReactFiberCommitWork.js | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js index 40b3a61e8e730..3a893c616e14a 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js @@ -7084,5 +7084,26 @@ background-color: green; , ); }); + + // @gate enableFloat + it('can update title tags', async () => { + const root = ReactDOMClient.createRoot(container); + await act(() => { + root.render(a title); + }); + await waitForAll([]); + + expect(getMeaningfulChildren(document.head)).toEqual( + a title, + ); + + await act(() => { + root.render(another title); + }); + await waitForAll([]); + expect(getMeaningfulChildren(document.head)).toEqual( + another title, + ); + }); }); }); diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.js b/packages/react-reconciler/src/ReactFiberCommitWork.js index 89c160df460a2..ef1a97815a653 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.js @@ -2692,7 +2692,7 @@ function commitMutationEffectsOnFiber( const updatePayload: null | UpdatePayload = (finishedWork.updateQueue: any); finishedWork.updateQueue = null; - if (updatePayload !== null) { + if (updatePayload !== null || diffInCommitPhase) { try { commitUpdate( finishedWork.stateNode, From b8a8b0ac43197b8978ca89d11e50c9f08f377492 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Mon, 19 Jun 2023 20:45:02 -0400 Subject: [PATCH 2/2] Clarify that updateHostComponent is unnecessary in the new flag We reuse updateHostComponent for HostSingleton and HostHoistables since it has a somewhat complex path but that means you have to remember when editing updateHostComponent that it's not just used for that tag. Luckily with the new flag, this is actually unnecessary since we just need to mark it for update if any props have changed and then we diff it later. --- .../src/ReactFiberCompleteWork.js | 49 ++++++++++++------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberCompleteWork.js b/packages/react-reconciler/src/ReactFiberCompleteWork.js index c70c1256a959d..63255e9e6ad78 100644 --- a/packages/react-reconciler/src/ReactFiberCompleteWork.js +++ b/packages/react-reconciler/src/ReactFiberCompleteWork.js @@ -1160,17 +1160,23 @@ function completeWork( return null; } else { // This is a Hoistable Instance - // - // We may have props to update on the Hoistable instance. We use the - // updateHostComponent path becuase it produces the update queue - // we need for Hoistables. - updateHostComponent( - current, - workInProgress, - type, - newProps, - renderLanes, - ); + // We may have props to update on the Hoistable instance. + if (diffInCommitPhase && supportsMutation) { + const oldProps = current.memoizedProps; + if (oldProps !== newProps) { + markUpdate(workInProgress); + } + } else { + // We use the updateHostComponent path becuase it produces + // the update queue we need for Hoistables. + updateHostComponent( + current, + workInProgress, + type, + newProps, + renderLanes, + ); + } // This must come at the very end of the complete phase. bubbleProperties(workInProgress); @@ -1192,13 +1198,20 @@ function completeWork( const rootContainerInstance = getRootHostContainer(); const type = workInProgress.type; if (current !== null && workInProgress.stateNode != null) { - updateHostComponent( - current, - workInProgress, - type, - newProps, - renderLanes, - ); + if (diffInCommitPhase && supportsMutation) { + const oldProps = current.memoizedProps; + if (oldProps !== newProps) { + markUpdate(workInProgress); + } + } else { + updateHostComponent( + current, + workInProgress, + type, + newProps, + renderLanes, + ); + } if (current.ref !== workInProgress.ref) { markRef(workInProgress);