Update error message for suspending at sync priority (#23361)
Instead of adding a new Suspense boundary, the default recommendation is to wrap the suspending update with startTransition.
This commit is contained in:
parent
8d0d0e9a8a
commit
3a60844a0f
|
@ -187,7 +187,7 @@ describe('ReactDOMServerSuspense', () => {
|
|||
1,
|
||||
);
|
||||
},
|
||||
'Add a <Suspense fallback=...> component higher in the tree',
|
||||
'A component suspended while responding to synchronous input.',
|
||||
);
|
||||
|
||||
itThrowsWhenRendering(
|
||||
|
@ -200,7 +200,7 @@ describe('ReactDOMServerSuspense', () => {
|
|||
1,
|
||||
);
|
||||
},
|
||||
'Add a <Suspense fallback=...> component higher in the tree',
|
||||
'A component suspended while responding to synchronous input.',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -78,11 +78,13 @@ function renderToStringImpl(
|
|||
}
|
||||
|
||||
if (!readyToStream) {
|
||||
// Note: This error message is the one we use on the client. It doesn't
|
||||
// really make sense here. But this is the legacy server renderer, anyway.
|
||||
// We're going to delete it soon.
|
||||
throw new Error(
|
||||
'A React component suspended while rendering, but no fallback UI was specified.\n' +
|
||||
'\n' +
|
||||
'Add a <Suspense fallback=...> component higher in the tree to ' +
|
||||
'provide a loading indicator or placeholder to display.',
|
||||
'A component suspended while responding to synchronous input. This ' +
|
||||
'will cause the UI to be replaced with a loading indicator. To fix, ' +
|
||||
'updates that suspend should be wrapped with startTransition.',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -499,15 +499,11 @@ function throwException(
|
|||
// This is a sync/discrete update. We treat this case like an error
|
||||
// because discrete renders are expected to produce a complete tree
|
||||
// synchronously to maintain consistency with external state.
|
||||
|
||||
// TODO: We should never call getComponentNameFromFiber in production.
|
||||
// Log a warning or something to prevent us from accidentally bundling it.
|
||||
const uncaughtSuspenseError = new Error(
|
||||
(getComponentNameFromFiber(sourceFiber) || 'A React component') +
|
||||
' suspended while rendering, but no fallback UI was specified.\n' +
|
||||
'\n' +
|
||||
'Add a <Suspense fallback=...> component higher in the tree to ' +
|
||||
'provide a loading indicator or placeholder to display.',
|
||||
'A component suspended while responding to synchronous input. This ' +
|
||||
'will cause the UI to be replaced with a loading indicator. To ' +
|
||||
'fix, updates that suspend should be wrapped ' +
|
||||
'with startTransition.',
|
||||
);
|
||||
|
||||
// If we're outside a transition, fall through to the regular error path.
|
||||
|
|
|
@ -499,15 +499,11 @@ function throwException(
|
|||
// This is a sync/discrete update. We treat this case like an error
|
||||
// because discrete renders are expected to produce a complete tree
|
||||
// synchronously to maintain consistency with external state.
|
||||
|
||||
// TODO: We should never call getComponentNameFromFiber in production.
|
||||
// Log a warning or something to prevent us from accidentally bundling it.
|
||||
const uncaughtSuspenseError = new Error(
|
||||
(getComponentNameFromFiber(sourceFiber) || 'A React component') +
|
||||
' suspended while rendering, but no fallback UI was specified.\n' +
|
||||
'\n' +
|
||||
'Add a <Suspense fallback=...> component higher in the tree to ' +
|
||||
'provide a loading indicator or placeholder to display.',
|
||||
'A component suspended while responding to synchronous input. This ' +
|
||||
'will cause the UI to be replaced with a loading indicator. To ' +
|
||||
'fix, updates that suspend should be wrapped ' +
|
||||
'with startTransition.',
|
||||
);
|
||||
|
||||
// If we're outside a transition, fall through to the regular error path.
|
||||
|
|
|
@ -1011,9 +1011,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
|||
ReactNoop.flushSync(() => {
|
||||
ReactNoop.render(<AsyncText text="Async" />);
|
||||
});
|
||||
}).toThrow(
|
||||
'AsyncText suspended while rendering, but no fallback UI was specified.',
|
||||
);
|
||||
}).toThrow('A component suspended while responding to synchronous input.');
|
||||
});
|
||||
|
||||
// @gate enableCache
|
||||
|
|
|
@ -409,5 +409,6 @@
|
|||
"421": "There was an error while hydrating this Suspense boundary. Switched to client rendering.",
|
||||
"422": "There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.",
|
||||
"423": "This root received an early update, before anything was able hydrate. Switched the entire root to client rendering.",
|
||||
"424": "Text content does not match server-rendered HTML."
|
||||
"424": "Text content does not match server-rendered HTML.",
|
||||
"425": "A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition."
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue