Skip to content

Commit c0decf3

Browse files
acdliten8schloss
authored andcommitted
Don't warn if an unmounted component is pinged (facebook#14158)
* Add failing test for ping on unmounted component We had a test for this, but not outside of concurrent mode :) * Don't warn if an unmounted component is pinged
1 parent 1b3a807 commit c0decf3

File tree

2 files changed

+88
-43
lines changed

2 files changed

+88
-43
lines changed

packages/react-reconciler/src/ReactFiberScheduler.js

Lines changed: 40 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,6 +1747,46 @@ function scheduleWorkToRoot(fiber: Fiber, expirationTime): FiberRoot | null {
17471747
}
17481748
}
17491749

1750+
if (enableSchedulerTracing) {
1751+
if (root !== null) {
1752+
const interactions = __interactionsRef.current;
1753+
if (interactions.size > 0) {
1754+
const pendingInteractionMap = root.pendingInteractionMap;
1755+
const pendingInteractions = pendingInteractionMap.get(expirationTime);
1756+
if (pendingInteractions != null) {
1757+
interactions.forEach(interaction => {
1758+
if (!pendingInteractions.has(interaction)) {
1759+
// Update the pending async work count for previously unscheduled interaction.
1760+
interaction.__count++;
1761+
}
1762+
1763+
pendingInteractions.add(interaction);
1764+
});
1765+
} else {
1766+
pendingInteractionMap.set(expirationTime, new Set(interactions));
1767+
1768+
// Update the pending async work count for the current interactions.
1769+
interactions.forEach(interaction => {
1770+
interaction.__count++;
1771+
});
1772+
}
1773+
1774+
const subscriber = __subscriberRef.current;
1775+
if (subscriber !== null) {
1776+
const threadID = computeThreadID(
1777+
expirationTime,
1778+
root.interactionThreadID,
1779+
);
1780+
subscriber.onWorkScheduled(interactions, threadID);
1781+
}
1782+
}
1783+
}
1784+
}
1785+
return root;
1786+
}
1787+
1788+
function scheduleWork(fiber: Fiber, expirationTime: ExpirationTime) {
1789+
const root = scheduleWorkToRoot(fiber, expirationTime);
17501790
if (root === null) {
17511791
if (__DEV__) {
17521792
switch (fiber.tag) {
@@ -1761,49 +1801,6 @@ function scheduleWorkToRoot(fiber: Fiber, expirationTime): FiberRoot | null {
17611801
break;
17621802
}
17631803
}
1764-
return null;
1765-
}
1766-
1767-
if (enableSchedulerTracing) {
1768-
const interactions = __interactionsRef.current;
1769-
if (interactions.size > 0) {
1770-
const pendingInteractionMap = root.pendingInteractionMap;
1771-
const pendingInteractions = pendingInteractionMap.get(expirationTime);
1772-
if (pendingInteractions != null) {
1773-
interactions.forEach(interaction => {
1774-
if (!pendingInteractions.has(interaction)) {
1775-
// Update the pending async work count for previously unscheduled interaction.
1776-
interaction.__count++;
1777-
}
1778-
1779-
pendingInteractions.add(interaction);
1780-
});
1781-
} else {
1782-
pendingInteractionMap.set(expirationTime, new Set(interactions));
1783-
1784-
// Update the pending async work count for the current interactions.
1785-
interactions.forEach(interaction => {
1786-
interaction.__count++;
1787-
});
1788-
}
1789-
1790-
const subscriber = __subscriberRef.current;
1791-
if (subscriber !== null) {
1792-
const threadID = computeThreadID(
1793-
expirationTime,
1794-
root.interactionThreadID,
1795-
);
1796-
subscriber.onWorkScheduled(interactions, threadID);
1797-
}
1798-
}
1799-
}
1800-
1801-
return root;
1802-
}
1803-
1804-
function scheduleWork(fiber: Fiber, expirationTime: ExpirationTime) {
1805-
const root = scheduleWorkToRoot(fiber, expirationTime);
1806-
if (root === null) {
18071804
return;
18081805
}
18091806

packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,5 +838,53 @@ describe('ReactSuspense', () => {
838838
]);
839839
expect(root).toMatchRenderedOutput('Tab: 2 + sibling');
840840
});
841+
842+
it('does not warn if an mounted component is pinged', () => {
843+
const {useState} = React;
844+
845+
const root = ReactTestRenderer.create(null);
846+
847+
let setStep;
848+
function UpdatingText({text, ms}) {
849+
const [step, _setStep] = useState(0);
850+
setStep = _setStep;
851+
const fullText = `${text}:${step}`;
852+
try {
853+
TextResource.read([fullText, ms]);
854+
ReactTestRenderer.unstable_yield(fullText);
855+
return fullText;
856+
} catch (promise) {
857+
if (typeof promise.then === 'function') {
858+
ReactTestRenderer.unstable_yield(`Suspend! [${fullText}]`);
859+
} else {
860+
ReactTestRenderer.unstable_yield(`Error! [${fullText}]`);
861+
}
862+
throw promise;
863+
}
864+
}
865+
866+
root.update(
867+
<Suspense fallback={<Text text="Loading..." />}>
868+
<UpdatingText text="A" ms={1000} />
869+
</Suspense>,
870+
);
871+
872+
expect(ReactTestRenderer).toHaveYielded(['Suspend! [A:0]', 'Loading...']);
873+
jest.advanceTimersByTime(1000);
874+
expect(ReactTestRenderer).toHaveYielded([
875+
'Promise resolved [A:0]',
876+
'A:0',
877+
]);
878+
expect(root).toMatchRenderedOutput('A:0');
879+
880+
setStep(1);
881+
expect(ReactTestRenderer).toHaveYielded(['Suspend! [A:1]', 'Loading...']);
882+
expect(root).toMatchRenderedOutput('Loading...');
883+
884+
root.update(null);
885+
expect(root).toFlushWithoutYielding();
886+
887+
jest.advanceTimersByTime(1000);
888+
});
841889
});
842890
});

0 commit comments

Comments
 (0)