From f818af9b03700f681bad0de6041e404cd681319d Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Wed, 18 Sep 2019 16:32:11 +0100 Subject: [PATCH] [Fresh] Always remount classes (#16823) --- .../src/ReactFiberHotReloading.js | 6 ++- .../__tests__/ReactFreshIntegration-test.js | 47 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/packages/react-reconciler/src/ReactFiberHotReloading.js b/packages/react-reconciler/src/ReactFiberHotReloading.js index 16d78a667709e..6392440d05d39 100644 --- a/packages/react-reconciler/src/ReactFiberHotReloading.js +++ b/packages/react-reconciler/src/ReactFiberHotReloading.js @@ -296,7 +296,11 @@ function scheduleFibersWithFamiliesRecursively( if (staleFamilies.has(family)) { needsRemount = true; } else if (updatedFamilies.has(family)) { - needsRender = true; + if (tag === ClassComponent) { + needsRemount = true; + } else { + needsRender = true; + } } } } diff --git a/packages/react-refresh/src/__tests__/ReactFreshIntegration-test.js b/packages/react-refresh/src/__tests__/ReactFreshIntegration-test.js index 4d1e5bf85c9be..b9110d8cc79ad 100644 --- a/packages/react-refresh/src/__tests__/ReactFreshIntegration-test.js +++ b/packages/react-refresh/src/__tests__/ReactFreshIntegration-test.js @@ -1299,6 +1299,53 @@ describe('ReactFreshIntegration', () => { } }); + it('remounts deprecated factory components', () => { + if (__DEV__) { + expect(() => { + render(` + function Parent() { + return { + render() { + return ; + } + }; + }; + + function Child({prop}) { + return

{prop}1

; + }; + + export default Parent; + `); + }).toWarnDev( + 'The component appears to be a function component ' + + 'that returns a class instance.', + {withoutStack: true}, + ); + const el = container.firstChild; + expect(el.textContent).toBe('A1'); + patch(` + function Parent() { + return { + render() { + return ; + } + }; + }; + + function Child({prop}) { + return

{prop}2

; + }; + + export default Parent; + `); + // Like classes, factory components always remount. + expect(container.firstChild).not.toBe(el); + const newEl = container.firstChild; + expect(newEl.textContent).toBe('B2'); + } + }); + describe('with inline requires', () => { beforeEach(() => { global.FakeModuleSystem = {};