[Fresh] Always remount classes (#16823)
Dan Abramov committed
Sep 18, 2019 at 16:32 UTC
f818af9b03700f681bad0de6041e404cd681319d
2 files changed
+52
-1
packages/react-reconciler/src/ReactFiberHotReloading.js
+5
-1
@@ -296,7 +296,11 @@ function scheduleFibersWithFamiliesRecursively(
296
if (staleFamilies.has(family)) {
297
needsRemount = true;
298
} else if (updatedFamilies.has(family)) {
299
- needsRender = true;
299
+ if (tag === ClassComponent) {
300
+ needsRemount = true;
301
+ } else {
302
+ needsRender = true;
303
+ }
304
}
305
}
306
}
packages/react-refresh/src/__tests__/ReactFreshIntegration-test.js
+47
@@ -1299,6 +1299,53 @@ describe('ReactFreshIntegration', () => {
1299
}
1300
});
1301
1302
+ it('remounts deprecated factory components', () => {
1303
+ if (__DEV__) {
1304
+ expect(() => {
1305
+ render(`
1306
+ function Parent() {
1307
+ return {
1308
+ render() {
1309
+ return <Child prop="A" />;
1310
+ }
1311
+ };
1312
+ };
1313
+
1314
+ function Child({prop}) {
1315
+ return <h1>{prop}1</h1>;
1316
+ };
1317
+
1318
+ export default Parent;
1319
+ `);
1320
+ }).toWarnDev(
1321
+ 'The <Parent /> component appears to be a function component ' +
1322
+ 'that returns a class instance.',
1323
+ {withoutStack: true},
1324
+ );
1325
+ const el = container.firstChild;
1326
+ expect(el.textContent).toBe('A1');
1327
+ patch(`
1328
+ function Parent() {
1329
+ return {
1330
+ render() {
1331
+ return <Child prop="B" />;
1332
+ }
1333
+ };
1334
+ };
1335
+
1336
+ function Child({prop}) {
1337
+ return <h1>{prop}2</h1>;
1338
+ };
1339
+
1340
+ export default Parent;
1341
+ `);
1342
+ // Like classes, factory components always remount.
1343
+ expect(container.firstChild).not.toBe(el);
1344
+ const newEl = container.firstChild;
1345
+ expect(newEl.textContent).toBe('B2');
1346
+ }
1347
+ });
1348
+
1349
describe('with inline requires', () => {
1350
beforeEach(() => {
1351
global.FakeModuleSystem = {};