@@ -16,8 +16,10 @@ let act;
16
16
let use ;
17
17
let useDebugValue ;
18
18
let useState ;
19
+ let useTransition ;
19
20
let useMemo ;
20
21
let useEffect ;
22
+ let useOptimistic ;
21
23
let Suspense ;
22
24
let startTransition ;
23
25
let pendingTextRequests ;
@@ -38,8 +40,10 @@ describe('ReactUse', () => {
38
40
use = React . use ;
39
41
useDebugValue = React . useDebugValue ;
40
42
useState = React . useState ;
43
+ useTransition = React . useTransition ;
41
44
useMemo = React . useMemo ;
42
45
useEffect = React . useEffect ;
46
+ useOptimistic = React . useOptimistic ;
43
47
Suspense = React . Suspense ;
44
48
startTransition = React . startTransition ;
45
49
@@ -1915,4 +1919,39 @@ describe('ReactUse', () => {
1915
1919
assertLog ( [ 'Hi' , 'World' ] ) ;
1916
1920
expect ( root ) . toMatchRenderedOutput ( < div > Hi World</ div > ) ;
1917
1921
} ) ;
1922
+
1923
+ it ( 'regression: does not get stuck in pending state after `use` suspends' , async ( ) => {
1924
+ // This is a regression test. The root cause was an issue where we failed to
1925
+ // switch from the "re-render" dispatcher back to the "update" dispatcher
1926
+ // after a `use` suspends and triggers a replay.
1927
+ let update ;
1928
+ function App ( { promise} ) {
1929
+ useState ( false ) ;
1930
+
1931
+ const value = use ( promise ) ;
1932
+
1933
+ const [ isPending , startLocalTransition ] = useTransition ( ) ;
1934
+ update = ( ) => {
1935
+ startLocalTransition ( ( ) => {
1936
+ root . render ( < App promise = { getAsyncText ( 'Updated' ) } /> ) ;
1937
+ } ) ;
1938
+ } ;
1939
+
1940
+ return < Text text = { value + ( isPending ? ' (pending...)' : '' ) } /> ;
1941
+ }
1942
+
1943
+ const root = ReactNoop . createRoot ( ) ;
1944
+ await act ( ( ) => {
1945
+ root . render ( < App promise = { Promise . resolve ( 'Initial' ) } /> ) ;
1946
+ } ) ;
1947
+ assertLog ( [ 'Initial' ] ) ;
1948
+ expect ( root ) . toMatchRenderedOutput ( 'Initial' ) ;
1949
+
1950
+ await act ( ( ) => update ( ) ) ;
1951
+ assertLog ( [ 'Async text requested [Updated]' , 'Initial (pending...)' ] ) ;
1952
+
1953
+ await act ( ( ) => resolveTextRequests ( 'Updated' ) ) ;
1954
+ assertLog ( [ 'Updated' ] ) ;
1955
+ expect ( root ) . toMatchRenderedOutput ( 'Updated' ) ;
1956
+ } ) ;
1918
1957
} ) ;
0 commit comments