update hideOrUnhideAllChildren to hide portals that aren't wrapped in a host component (#16992)
Currently, when a node suspends, if its subtree contains a portal, the portal is not hidden. This hides portals in the subtree when it's not wrapped in a host component .
Luna Ruan committed
Oct 2, 2019 at 15:30 UTC
de2edc268db827f5110fc56cba240b7eb7301787
2 files changed
+30
packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.js
+23
@@ -104,6 +104,29 @@ describe('ReactDOMSuspensePlaceholder', () => {
104
expect(window.getComputedStyle(divs[2].current).display).toEqual('inline');
105
});
106
107
+ it('hides and unhides child portals', async () => {
108
+ const portalContainer = document.createElement('div');
109
+ function Component() {
110
+ return ReactDOM.createPortal(<span />, portalContainer);
111
+ }
112
+
113
+ function App() {
114
+ return (
115
+ <Suspense fallback={<Text text="Loading..." />}>
116
+ <AsyncText ms={500} text="A" />
117
+ <Component />
118
+ </Suspense>
119
+ );
120
+ }
121
+
122
+ ReactDOM.render(<App />, container);
123
+ expect(window.getComputedStyle(portalContainer).display).toEqual('none');
124
+
125
+ await advanceTimers(500);
126
+ Scheduler.unstable_flushAll();
127
+ expect(window.getComputedStyle(portalContainer).display).toEqual('block');
128
+ });
129
+
130
it('hides and unhides timed out text nodes', async () => {
131
function App() {
132
return (
packages/react-reconciler/src/ReactFiberCommitWork.js
+7
@@ -645,6 +645,13 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) {
645
} else {
646
unhideInstance(node.stateNode, node.memoizedProps);
647
}
648
+ } else if (node.tag === HostPortal) {
649
+ const instance = node.stateNode.containerInfo;
650
+ if (isHidden) {
651
+ hideInstance(instance);
652
+ } else {
653
+ unhideInstance(instance, node.memoizedProps);
654
+ }
655
} else if (node.tag === HostText) {
656
const instance = node.stateNode;
657
if (isHidden) {