diff --git a/packages/react-reconciler/src/__tests__/ReactUse-test.js b/packages/react-reconciler/src/__tests__/ReactUse-test.js
index dede68854c615..a9f8ca4313347 100644
--- a/packages/react-reconciler/src/__tests__/ReactUse-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactUse-test.js
@@ -16,6 +16,7 @@ let act;
let use;
let useDebugValue;
let useState;
+let useTransition;
let useMemo;
let useEffect;
let Suspense;
@@ -38,6 +39,7 @@ describe('ReactUse', () => {
use = React.use;
useDebugValue = React.useDebugValue;
useState = React.useState;
+ useTransition = React.useTransition;
useMemo = React.useMemo;
useEffect = React.useEffect;
Suspense = React.Suspense;
@@ -1915,4 +1917,62 @@ describe('ReactUse', () => {
assertLog(['Hi', 'World']);
expect(root).toMatchRenderedOutput(
Hi World
);
});
+
+ it('does not get stuck in pending state with usable values in state', async () => {
+ const initial = new Promise(resolve => {
+ setTimeout(() => {
+ resolve('initial');
+ }, 1000);
+ });
+ let click;
+ function Reader({promise, setPromise}) {
+ const value = use(promise);
+ const [isPending, startLocalTransition] = useTransition();
+ click = () => {
+ startLocalTransition(() => {
+ setPromise(
+ new Promise(resolve => {
+ setTimeout(() => {
+ resolve('updated');
+ }, 1000);
+ }),
+ );
+ });
+ };
+
+ Scheduler.log(`Value: ${value}, Pending: ${String(isPending)}`);
+
+ return (
+ <>
+ Value: {value}, Pending: {String(isPending)}
+ >
+ );
+ }
+ function App() {
+ const [promise, setPromise] = useState(initial);
+
+ return (
+
+
+
+ );
+ }
+
+ const root = ReactNoop.createRoot();
+ await act(() => {
+ root.render();
+ });
+ assertLog(['Value: initial, Pending: false']);
+ expect(root).toMatchRenderedOutput('Value: initial, Pending: false');
+
+ await act(() => {
+ click();
+ });
+
+ assertLog([
+ 'Value: initial, Pending: true',
+ 'Value: updated, Pending: true',
+ ]);
+ expect(root).toMatchRenderedOutput('Value: updated, Pending: true');
+ });
});