@@ -73,6 +73,7 @@ const api = createApi({
73
73
data : arg ?. body ? { ...arg . body , ...( amount ? { amount } : { } ) } : { } ,
74
74
}
75
75
} ,
76
+ tagTypes : [ 'IncrementedAmount' ] ,
76
77
endpoints : ( build ) => ( {
77
78
getUser : build . query < { name : string } , number > ( {
78
79
query : ( ) => ( {
@@ -93,6 +94,13 @@ const api = createApi({
93
94
amount,
94
95
} ,
95
96
} ) ,
97
+ providesTags : [ 'IncrementedAmount' ] ,
98
+ } ) ,
99
+ triggerUpdatedAmount : build . mutation < void , void > ( {
100
+ queryFn : async ( ) => {
101
+ return { data : undefined }
102
+ } ,
103
+ invalidatesTags : [ 'IncrementedAmount' ] ,
96
104
} ) ,
97
105
updateUser : build . mutation < { name : string } , { name : string } > ( {
98
106
query : ( update ) => ( { body : update } ) ,
@@ -1375,6 +1383,101 @@ describe('hooks tests', () => {
1375
1383
1376
1384
expect ( screen . getByTestId ( 'error' ) . textContent ) . toBe ( '' )
1377
1385
} )
1386
+
1387
+ test ( 'useLazyQuery trigger promise returns the correctly updated data' , async ( ) => {
1388
+ const LazyUnwrapUseEffect = ( ) => {
1389
+ const [
1390
+ triggerGetIncrementedAmount ,
1391
+ { isFetching, isSuccess, isError, error, data } ,
1392
+ ] = api . endpoints . getIncrementedAmount . useLazyQuery ( )
1393
+
1394
+ type AmountData = { amount : number } | undefined
1395
+
1396
+ const [ triggerUpdate ] = api . endpoints . triggerUpdatedAmount . useMutation ( )
1397
+
1398
+ const [ dataFromQuery , setDataFromQuery ] =
1399
+ useState < AmountData > ( undefined )
1400
+ const [ dataFromTrigger , setDataFromTrigger ] =
1401
+ useState < AmountData > ( undefined )
1402
+
1403
+ const handleLoad = async ( ) => {
1404
+ try {
1405
+ const res = await triggerGetIncrementedAmount ( ) . unwrap ( )
1406
+
1407
+ setDataFromTrigger ( res ) // adding client side state here will cause stale data
1408
+ } catch ( error ) {
1409
+ console . error ( error )
1410
+ }
1411
+ }
1412
+
1413
+ const handleMutate = async ( ) => {
1414
+ try {
1415
+ await triggerUpdate ( )
1416
+ // Force the lazy trigger to refetch
1417
+ await handleLoad ( )
1418
+ } catch ( error ) {
1419
+ console . error ( error )
1420
+ }
1421
+ }
1422
+
1423
+ useEffect ( ( ) => {
1424
+ // Intentionally copy to local state for comparison purposes
1425
+ setDataFromQuery ( data )
1426
+ } , [ data ] )
1427
+
1428
+ let content : React . ReactNode | null = null
1429
+
1430
+ if ( isFetching ) {
1431
+ content = < div className = "loading" > Loading</ div >
1432
+ } else if ( isSuccess ) {
1433
+ content = (
1434
+ < div className = "wrapper" >
1435
+ < div >
1436
+ useEffect data: { dataFromQuery ?. amount ?? 'No query amount' }
1437
+ </ div >
1438
+ < div >
1439
+ Unwrap data: { dataFromTrigger ?. amount ?? 'No trigger amount' }
1440
+ </ div >
1441
+ </ div >
1442
+ )
1443
+ }
1444
+
1445
+ return (
1446
+ < div className = "outer" >
1447
+ < button onClick = { ( ) => handleLoad ( ) } > Load Data</ button >
1448
+ < button onClick = { ( ) => handleMutate ( ) } > Update Data</ button >
1449
+ { content }
1450
+ </ div >
1451
+ )
1452
+ }
1453
+
1454
+ render ( < LazyUnwrapUseEffect /> , { wrapper : storeRef . wrapper } )
1455
+
1456
+ // Kick off the initial fetch via lazy query trigger
1457
+ act ( ( ) => {
1458
+ userEvent . click ( screen . getByText ( 'Load Data' ) )
1459
+ } )
1460
+
1461
+ // We get back initial data, which should get copied into local state,
1462
+ // and also should come back as valid via the lazy trigger promise
1463
+ await waitFor ( ( ) => {
1464
+ expect ( screen . getByText ( 'useEffect data: 1' ) ) . toBeTruthy ( )
1465
+ expect ( screen . getByText ( 'Unwrap data: 1' ) ) . toBeTruthy ( )
1466
+ } )
1467
+
1468
+ // If we mutate and then re-run the lazy trigger afterwards...
1469
+ act ( ( ) => {
1470
+ userEvent . click ( screen . getByText ( 'Update Data' ) )
1471
+ } )
1472
+
1473
+ // We should see both sets of data agree (ie, the lazy trigger promise
1474
+ // should not return stale data or be out of sync with the hook).
1475
+ // Prior to PR #4651, this would fail because the trigger never updated properly.
1476
+ await waitFor ( ( ) => {
1477
+ expect ( screen . getByText ( 'useEffect data: 2' ) ) . toBeTruthy ( )
1478
+ expect ( screen . getByText ( 'Unwrap data: 2' ) ) . toBeTruthy ( )
1479
+ } )
1480
+ } )
1378
1481
} )
1379
1482
1380
1483
describe ( 'useMutation' , ( ) => {
0 commit comments