mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Remove false positive warning and add TODOs about current being non-null (#14821)
* Failing test for false positive warning * Add tests for forwardRef too * Remove the warning and add TODOs
This commit is contained in:
@@ -220,6 +220,10 @@ function updateForwardRef(
|
||||
nextProps: any,
|
||||
renderExpirationTime: ExpirationTime,
|
||||
) {
|
||||
// TODO: current can be non-null here even if the component
|
||||
// hasn't yet mounted. This happens after the first render suspends.
|
||||
// We'll need to figure out if this is fine or can cause issues.
|
||||
|
||||
if (__DEV__) {
|
||||
if (workInProgress.type !== workInProgress.elementType) {
|
||||
// Lazy component props can't be validated in createElement
|
||||
@@ -415,6 +419,10 @@ function updateSimpleMemoComponent(
|
||||
updateExpirationTime,
|
||||
renderExpirationTime: ExpirationTime,
|
||||
): null | Fiber {
|
||||
// TODO: current can be non-null here even if the component
|
||||
// hasn't yet mounted. This happens when the inner render suspends.
|
||||
// We'll need to figure out if this is fine or can cause issues.
|
||||
|
||||
if (__DEV__) {
|
||||
if (workInProgress.type !== workInProgress.elementType) {
|
||||
// Lazy component props can't be validated in createElement
|
||||
|
||||
@@ -449,17 +449,6 @@ function mountWorkInProgressHook(): Hook {
|
||||
|
||||
if (__DEV__) {
|
||||
(hook: any)._debugType = (currentHookNameInDev: any);
|
||||
if (
|
||||
currentlyRenderingFiber !== null &&
|
||||
currentlyRenderingFiber.alternate !== null
|
||||
) {
|
||||
warning(
|
||||
false,
|
||||
'%s: Rendered more hooks than during the previous render. This is ' +
|
||||
'not currently supported and may lead to unexpected behavior.',
|
||||
getComponentName(currentlyRenderingFiber.type),
|
||||
);
|
||||
}
|
||||
}
|
||||
if (workInProgressHook === null) {
|
||||
// This is the first hook in the list
|
||||
|
||||
@@ -1366,4 +1366,97 @@ describe('ReactHooks', () => {
|
||||
),
|
||||
).toThrow('Hello');
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/facebook/react/issues/14790
|
||||
it('does not fire a false positive warning when suspending memo', async () => {
|
||||
const {Suspense, useState} = React;
|
||||
|
||||
let wasSuspended = false;
|
||||
function trySuspend() {
|
||||
if (!wasSuspended) {
|
||||
throw new Promise(resolve => {
|
||||
wasSuspended = true;
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function Child() {
|
||||
useState();
|
||||
trySuspend();
|
||||
return 'hello';
|
||||
}
|
||||
|
||||
const Wrapper = React.memo(Child);
|
||||
const root = ReactTestRenderer.create(
|
||||
<Suspense fallback="loading">
|
||||
<Wrapper />
|
||||
</Suspense>,
|
||||
);
|
||||
expect(root).toMatchRenderedOutput('loading');
|
||||
await Promise.resolve();
|
||||
expect(root).toMatchRenderedOutput('hello');
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/facebook/react/issues/14790
|
||||
it('does not fire a false positive warning when suspending forwardRef', async () => {
|
||||
const {Suspense, useState} = React;
|
||||
|
||||
let wasSuspended = false;
|
||||
function trySuspend() {
|
||||
if (!wasSuspended) {
|
||||
throw new Promise(resolve => {
|
||||
wasSuspended = true;
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function render(props, ref) {
|
||||
useState();
|
||||
trySuspend();
|
||||
return 'hello';
|
||||
}
|
||||
|
||||
const Wrapper = React.forwardRef(render);
|
||||
const root = ReactTestRenderer.create(
|
||||
<Suspense fallback="loading">
|
||||
<Wrapper />
|
||||
</Suspense>,
|
||||
);
|
||||
expect(root).toMatchRenderedOutput('loading');
|
||||
await Promise.resolve();
|
||||
expect(root).toMatchRenderedOutput('hello');
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/facebook/react/issues/14790
|
||||
it('does not fire a false positive warning when suspending memo(forwardRef)', async () => {
|
||||
const {Suspense, useState} = React;
|
||||
|
||||
let wasSuspended = false;
|
||||
function trySuspend() {
|
||||
if (!wasSuspended) {
|
||||
throw new Promise(resolve => {
|
||||
wasSuspended = true;
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function render(props, ref) {
|
||||
useState();
|
||||
trySuspend();
|
||||
return 'hello';
|
||||
}
|
||||
|
||||
const Wrapper = React.memo(React.forwardRef(render));
|
||||
const root = ReactTestRenderer.create(
|
||||
<Suspense fallback="loading">
|
||||
<Wrapper />
|
||||
</Suspense>,
|
||||
);
|
||||
expect(root).toMatchRenderedOutput('loading');
|
||||
await Promise.resolve();
|
||||
expect(root).toMatchRenderedOutput('hello');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user