Skip to content

Commit 2047f54

Browse files
authored
Handle additional serializeQueryArgs + skipToken case (#4762)
* Handle skipToken in queryStatePreSelector * Add invalidationBehavior docblock to API ref
1 parent 40b8aed commit 2047f54

File tree

3 files changed

+54
-7
lines changed

3 files changed

+54
-7
lines changed

docs/rtk-query/api/createApi.mdx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export const { useGetPokemonByNameQuery } = pokemonApi
5454
// highlight-end
5555
```
5656

57-
## Parameters
57+
## `createApi` Parameters
5858

5959
`createApi` accepts a single configuration object parameter with the following options:
6060

@@ -357,6 +357,10 @@ See also [Server Side Rendering](../usage/server-side-rendering.mdx) and
357357

358358
By default, this function will take the query arguments, sort object keys where applicable, stringify the result, and concatenate it with the endpoint name. This creates a cache key based on the combination of arguments + endpoint name (ignoring object key order), such that calling any given endpoint with the same arguments will result in the same cache key.
359359

360+
### `invalidationBehavior`
361+
362+
[summary](docblock://query/createApi.ts?token=CreateApiOptions.invalidationBehavior)
363+
360364
### `keepUnusedDataFor`
361365

362366
[summary](docblock://query/createApi.ts?token=CreateApiOptions.keepUnusedDataFor)
@@ -389,7 +393,7 @@ You can set this globally in `createApi`, but you can also override the default
389393
If you specify `track: false` when manually dispatching queries, RTK Query will not be able to automatically refetch for you.
390394
:::
391395

392-
## Anatomy of an endpoint
396+
## Endpoint Definition Parameters
393397

394398
### `query`
395399

packages/toolkit/src/query/react/buildHooks.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -905,16 +905,17 @@ export function buildHooks<Definitions extends EndpointDefinitions>({
905905
const { endpointName } = lastResult
906906
const endpointDefinition = context.endpointDefinitions[endpointName]
907907
if (
908+
queryArgs !== skipToken &&
908909
serializeQueryArgs({
909910
queryArgs: lastResult.originalArgs,
910911
endpointDefinition,
911912
endpointName,
912913
}) ===
913-
serializeQueryArgs({
914-
queryArgs,
915-
endpointDefinition,
916-
endpointName,
917-
})
914+
serializeQueryArgs({
915+
queryArgs,
916+
endpointDefinition,
917+
endpointName,
918+
})
918919
)
919920
lastResult = undefined
920921
}

packages/toolkit/src/query/tests/buildHooks.test.tsx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3077,6 +3077,48 @@ describe('skip behavior', () => {
30773077
expect(getSubscriptionCount('getUser(1)')).toBe(0)
30783078
})
30793079

3080+
test('skipToken does not break serializeQueryArgs', async () => {
3081+
const { result, rerender } = renderHook(
3082+
([arg, options]: Parameters<
3083+
typeof api.endpoints.queryWithDeepArg.useQuery
3084+
>) => api.endpoints.queryWithDeepArg.useQuery(arg, options),
3085+
{
3086+
wrapper: storeRef.wrapper,
3087+
initialProps: [skipToken],
3088+
},
3089+
)
3090+
3091+
expect(result.current).toEqual(uninitialized)
3092+
await waitMs(1)
3093+
3094+
expect(getSubscriptionCount('nestedValue')).toBe(0)
3095+
// also no subscription on `getUser(skipToken)` or similar:
3096+
expect(getSubscriptions()).toEqual({})
3097+
3098+
rerender([{ param: { nested: 'nestedValue' } }])
3099+
3100+
await act(async () => {
3101+
await waitForFakeTimer(150)
3102+
})
3103+
3104+
expect(result.current).toMatchObject({ status: QueryStatus.fulfilled })
3105+
await waitMs(1)
3106+
3107+
expect(getSubscriptionCount('nestedValue')).toBe(1)
3108+
expect(getSubscriptions()).not.toEqual({})
3109+
3110+
rerender([skipToken])
3111+
3112+
expect(result.current).toEqual({
3113+
...uninitialized,
3114+
isSuccess: true,
3115+
currentData: undefined,
3116+
data: {},
3117+
})
3118+
await waitMs(1)
3119+
expect(getSubscriptionCount('nestedValue')).toBe(0)
3120+
})
3121+
30803122
test('skipping a previously fetched query retains the existing value as `data`, but clears `currentData`', async () => {
30813123
const { result, rerender } = renderHook(
30823124
([arg, options]: Parameters<typeof api.endpoints.getUser.useQuery>) =>

0 commit comments

Comments
 (0)