From 5c306e6a80ae85e20e7267889abd3ff6efb0658f Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 12 Nov 2018 18:31:46 +0000 Subject: [PATCH 1/2] Add another (failing) regression test for #14188 --- ...actDOMSuspensePlaceholder-test.internal.js | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.internal.js index 98069e2d9f40..bdd7a3bf7269 100644 --- a/packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.internal.js @@ -222,4 +222,48 @@ describe('ReactDOMSuspensePlaceholder', () => { await Lazy; expect(log).toEqual(['cDU first', 'cDU second']); }); + + // Regression test for https://github.com/facebook/react/issues/14188 + it('can call findDOMNode() in a suspended component commit phase (#2)', () => { + let suspendOnce = Promise.resolve(); + function Suspend() { + if (suspendOnce) { + let promise = suspendOnce; + suspendOnce = null; + throw promise; + } + return null; + } + + const log = []; + class Child extends React.Component { + componentDidMount() { + log.push('cDM'); + ReactDOM.findDOMNode(this); + } + + componentDidUpdate() { + log.push('cDU'); + ReactDOM.findDOMNode(this); + } + + render() { + return null; + } + } + + function App() { + return ( + + + + + ); + } + + ReactDOM.render(, container); + // expect(log).toEqual([]); + ReactDOM.render(, container); + // expect(log).toEqual(['cDM']); + }); }); From 6a7d3a0bf453ee2a19a5b30dfab4ebc254c86bf0 Mon Sep 17 00:00:00 2001 From: Sophie Alpert Date: Thu, 6 Dec 2018 14:58:47 -0800 Subject: [PATCH 2/2] Fix findCurrentFiberUsingSlowPath w/ no alternate --- .../ReactDOMSuspensePlaceholder-test.internal.js | 4 ++-- .../src/ReactFiberTreeReflection.js | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.internal.js index bdd7a3bf7269..9536460d9fff 100644 --- a/packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.internal.js @@ -262,8 +262,8 @@ describe('ReactDOMSuspensePlaceholder', () => { } ReactDOM.render(, container); - // expect(log).toEqual([]); + expect(log).toEqual(['cDM']); ReactDOM.render(, container); - // expect(log).toEqual(['cDM']); + expect(log).toEqual(['cDM', 'cDU']); }); }); diff --git a/packages/react-reconciler/src/ReactFiberTreeReflection.js b/packages/react-reconciler/src/ReactFiberTreeReflection.js index f2c3e37b699e..dfb4c5532367 100644 --- a/packages/react-reconciler/src/ReactFiberTreeReflection.js +++ b/packages/react-reconciler/src/ReactFiberTreeReflection.js @@ -117,16 +117,17 @@ export function findCurrentFiberUsingSlowPath(fiber: Fiber): Fiber | null { let b = alternate; while (true) { let parentA = a.return; - let parentB = parentA ? parentA.alternate : null; - if (!parentA || !parentB) { + if (!parentA) { // We're at the root. break; } - // If both copies of the parent fiber point to the same child, we can - // assume that the child is current. This happens when we bailout on low - // priority: the bailed out fiber's child reuses the current child. - if (parentA.child === parentB.child) { + // If both copies of the parent fiber point to the same child (or if there + // is only a single parent fiber), we can assume that the child is current. + // This happens when we bailout on low priority: the bailed out fiber's + // child reuses the current child. + let parentB = parentA.alternate; + if (parentB === null || parentA.child === parentB.child) { let child = parentA.child; while (child) { if (child === a) {