Skip to content

Commit c6bee76

Browse files
authored
Remove false positive warning and add TODOs about current being non-null (facebook#14821)
* Failing test for false positive warning * Add tests for forwardRef too * Remove the warning and add TODOs
1 parent 3ae94e1 commit c6bee76

File tree

3 files changed

+101
-11
lines changed

3 files changed

+101
-11
lines changed

packages/react-reconciler/src/ReactFiberBeginWork.js

+8
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ function updateForwardRef(
220220
nextProps: any,
221221
renderExpirationTime: ExpirationTime,
222222
) {
223+
// TODO: current can be non-null here even if the component
224+
// hasn't yet mounted. This happens after the first render suspends.
225+
// We'll need to figure out if this is fine or can cause issues.
226+
223227
if (__DEV__) {
224228
if (workInProgress.type !== workInProgress.elementType) {
225229
// Lazy component props can't be validated in createElement
@@ -415,6 +419,10 @@ function updateSimpleMemoComponent(
415419
updateExpirationTime,
416420
renderExpirationTime: ExpirationTime,
417421
): null | Fiber {
422+
// TODO: current can be non-null here even if the component
423+
// hasn't yet mounted. This happens when the inner render suspends.
424+
// We'll need to figure out if this is fine or can cause issues.
425+
418426
if (__DEV__) {
419427
if (workInProgress.type !== workInProgress.elementType) {
420428
// Lazy component props can't be validated in createElement

packages/react-reconciler/src/ReactFiberHooks.js

-11
Original file line numberDiff line numberDiff line change
@@ -449,17 +449,6 @@ function mountWorkInProgressHook(): Hook {
449449

450450
if (__DEV__) {
451451
(hook: any)._debugType = (currentHookNameInDev: any);
452-
if (
453-
currentlyRenderingFiber !== null &&
454-
currentlyRenderingFiber.alternate !== null
455-
) {
456-
warning(
457-
false,
458-
'%s: Rendered more hooks than during the previous render. This is ' +
459-
'not currently supported and may lead to unexpected behavior.',
460-
getComponentName(currentlyRenderingFiber.type),
461-
);
462-
}
463452
}
464453
if (workInProgressHook === null) {
465454
// This is the first hook in the list

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

+93
Original file line numberDiff line numberDiff line change
@@ -1366,4 +1366,97 @@ describe('ReactHooks', () => {
13661366
),
13671367
).toThrow('Hello');
13681368
});
1369+
1370+
// Regression test for https://github.com/facebook/react/issues/14790
1371+
it('does not fire a false positive warning when suspending memo', async () => {
1372+
const {Suspense, useState} = React;
1373+
1374+
let wasSuspended = false;
1375+
function trySuspend() {
1376+
if (!wasSuspended) {
1377+
throw new Promise(resolve => {
1378+
wasSuspended = true;
1379+
resolve();
1380+
});
1381+
}
1382+
}
1383+
1384+
function Child() {
1385+
useState();
1386+
trySuspend();
1387+
return 'hello';
1388+
}
1389+
1390+
const Wrapper = React.memo(Child);
1391+
const root = ReactTestRenderer.create(
1392+
<Suspense fallback="loading">
1393+
<Wrapper />
1394+
</Suspense>,
1395+
);
1396+
expect(root).toMatchRenderedOutput('loading');
1397+
await Promise.resolve();
1398+
expect(root).toMatchRenderedOutput('hello');
1399+
});
1400+
1401+
// Regression test for https://github.com/facebook/react/issues/14790
1402+
it('does not fire a false positive warning when suspending forwardRef', async () => {
1403+
const {Suspense, useState} = React;
1404+
1405+
let wasSuspended = false;
1406+
function trySuspend() {
1407+
if (!wasSuspended) {
1408+
throw new Promise(resolve => {
1409+
wasSuspended = true;
1410+
resolve();
1411+
});
1412+
}
1413+
}
1414+
1415+
function render(props, ref) {
1416+
useState();
1417+
trySuspend();
1418+
return 'hello';
1419+
}
1420+
1421+
const Wrapper = React.forwardRef(render);
1422+
const root = ReactTestRenderer.create(
1423+
<Suspense fallback="loading">
1424+
<Wrapper />
1425+
</Suspense>,
1426+
);
1427+
expect(root).toMatchRenderedOutput('loading');
1428+
await Promise.resolve();
1429+
expect(root).toMatchRenderedOutput('hello');
1430+
});
1431+
1432+
// Regression test for https://github.com/facebook/react/issues/14790
1433+
it('does not fire a false positive warning when suspending memo(forwardRef)', async () => {
1434+
const {Suspense, useState} = React;
1435+
1436+
let wasSuspended = false;
1437+
function trySuspend() {
1438+
if (!wasSuspended) {
1439+
throw new Promise(resolve => {
1440+
wasSuspended = true;
1441+
resolve();
1442+
});
1443+
}
1444+
}
1445+
1446+
function render(props, ref) {
1447+
useState();
1448+
trySuspend();
1449+
return 'hello';
1450+
}
1451+
1452+
const Wrapper = React.memo(React.forwardRef(render));
1453+
const root = ReactTestRenderer.create(
1454+
<Suspense fallback="loading">
1455+
<Wrapper />
1456+
</Suspense>,
1457+
);
1458+
expect(root).toMatchRenderedOutput('loading');
1459+
await Promise.resolve();
1460+
expect(root).toMatchRenderedOutput('hello');
1461+
});
13691462
});

0 commit comments

Comments
 (0)