Skip to content

Commit e0d4e2e

Browse files
committed
Replace useStableQueryArgs with structural sharing
1 parent af3e75b commit e0d4e2e

File tree

2 files changed

+14
-57
lines changed

2 files changed

+14
-57
lines changed

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

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,7 @@ import type {
3939
TSHelpersNoInfer,
4040
TSHelpersOverride,
4141
} from '@reduxjs/toolkit/query'
42-
import {
43-
defaultSerializeQueryArgs,
44-
QueryStatus,
45-
skipToken,
46-
} from '@reduxjs/toolkit/query'
42+
import { QueryStatus, skipToken } from '@reduxjs/toolkit/query'
4743
import type { DependencyList } from 'react'
4844
import {
4945
useCallback,
@@ -1644,17 +1640,7 @@ export function buildHooks<Definitions extends EndpointDefinitions>({
16441640
subscriptionSelectorsRef.current =
16451641
returnedValue as unknown as SubscriptionSelectors
16461642
}
1647-
const stableArg = useStableQueryArgs(
1648-
skip ? skipToken : arg,
1649-
// Even if the user provided a per-endpoint `serializeQueryArgs` with
1650-
// a consistent return value, _here_ we want to use the default behavior
1651-
// so we can tell if _anything_ actually changed. Otherwise, we can end up
1652-
// with a case where the query args did change but the serialization doesn't,
1653-
// and then we never try to initiate a refetch.
1654-
defaultSerializeQueryArgs,
1655-
context.endpointDefinitions[endpointName],
1656-
endpointName,
1657-
)
1643+
const stableArg = useStableQueryArgs(skip ? skipToken : arg)
16581644
const stableSubscriptionOptions = useShallowStableValue({
16591645
refetchOnReconnect,
16601646
refetchOnFocus,
@@ -1764,12 +1750,7 @@ export function buildHooks<Definitions extends EndpointDefinitions>({
17641750
QueryDefinition<any, any, any, any, any>,
17651751
Definitions
17661752
>
1767-
const stableArg = useStableQueryArgs(
1768-
skip ? skipToken : arg,
1769-
serializeQueryArgs,
1770-
context.endpointDefinitions[endpointName],
1771-
endpointName,
1772-
)
1753+
const stableArg = useStableQueryArgs(skip ? skipToken : arg)
17731754

17741755
type ApiRootState = Parameters<ReturnType<typeof select>>[0]
17751756

@@ -2053,17 +2034,7 @@ export function buildHooks<Definitions extends EndpointDefinitions>({
20532034

20542035
usePromiseRefUnsubscribeOnUnmount(promiseRef)
20552036

2056-
const stableArg = useStableQueryArgs(
2057-
options.skip ? skipToken : arg,
2058-
// Even if the user provided a per-endpoint `serializeQueryArgs` with
2059-
// a consistent return value, _here_ we want to use the default behavior
2060-
// so we can tell if _anything_ actually changed. Otherwise, we can end up
2061-
// with a case where the query args did change but the serialization doesn't,
2062-
// and then we never try to initiate a refetch.
2063-
defaultSerializeQueryArgs,
2064-
context.endpointDefinitions[endpointName],
2065-
endpointName,
2066-
)
2037+
const stableArg = useStableQueryArgs(options.skip ? skipToken : arg)
20672038

20682039
const refetch = useCallback(
20692040
() => refetchOrErrorIfUnmounted(promiseRef),
Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,17 @@
11
import { useEffect, useRef, useMemo } from 'react'
2-
import type { SerializeQueryArgs } from '@reduxjs/toolkit/query'
3-
import type { EndpointDefinition } from '@reduxjs/toolkit/query'
2+
import { copyWithStructuralSharing } from '@reduxjs/toolkit/query'
43

5-
export function useStableQueryArgs<T>(
6-
queryArgs: T,
7-
serialize: SerializeQueryArgs<any>,
8-
endpointDefinition: EndpointDefinition<any, any, any, any>,
9-
endpointName: string,
10-
) {
11-
const incoming = useMemo(
12-
() => ({
13-
queryArgs,
14-
serialized:
15-
typeof queryArgs == 'object'
16-
? serialize({ queryArgs, endpointDefinition, endpointName })
17-
: queryArgs,
18-
}),
19-
[queryArgs, serialize, endpointDefinition, endpointName],
4+
export function useStableQueryArgs<T>(queryArgs: T) {
5+
const cache = useRef(queryArgs)
6+
const copy = useMemo(
7+
() => copyWithStructuralSharing(cache.current, queryArgs),
8+
[queryArgs],
209
)
21-
const cache = useRef(incoming)
2210
useEffect(() => {
23-
if (cache.current.serialized !== incoming.serialized) {
24-
cache.current = incoming
11+
if (cache.current !== copy) {
12+
cache.current = copy
2513
}
26-
}, [incoming])
14+
}, [copy])
2715

28-
return cache.current.serialized === incoming.serialized
29-
? cache.current.queryArgs
30-
: queryArgs
16+
return copy
3117
}

0 commit comments

Comments
 (0)