Skip to content

Commit e2dff71

Browse files
committed
refactor to remove code duplication
1 parent ea5ea71 commit e2dff71

File tree

2 files changed

+12
-35
lines changed

2 files changed

+12
-35
lines changed

packages/toolkit/src/query/defaultSerializeQueryArgs.ts

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,7 @@ const cache: WeakMap<any, string> | undefined = WeakMap
99
export const defaultSerializeQueryArgs: SerializeQueryArgs<any> = ({
1010
endpointName,
1111
queryArgs,
12-
}) => {
13-
let serialized = ''
14-
15-
const cached = cache?.get(queryArgs)
16-
17-
if (typeof cached === 'string') {
18-
serialized = cached
19-
} else {
20-
const stringified = JSON.stringify(queryArgs, (key, value) =>
21-
// Sort the object keys before stringifying, to prevent useQuery({ a: 1, b: 2 }) having a different cache key than useQuery({ b: 2, a: 1 })
22-
isPlainObject(value)
23-
? Object.keys(value)
24-
.sort()
25-
.reduce<any>((acc, key) => {
26-
acc[key] = (value as any)[key]
27-
return acc
28-
}, {})
29-
: value,
30-
)
31-
if (isPlainObject(queryArgs)) {
32-
cache?.set(queryArgs, stringified)
33-
}
34-
serialized = stringified
35-
}
36-
return `${endpointName}(${serialized})`
37-
}
38-
39-
export const bigIntSafeSerializeQueryArgs: SerializeQueryArgs<any> = ({
40-
endpointName,
41-
queryArgs,
12+
replacer,
4213
}) => {
4314
let serialized = ''
4415

@@ -48,8 +19,8 @@ export const bigIntSafeSerializeQueryArgs: SerializeQueryArgs<any> = ({
4819
serialized = cached
4920
} else {
5021
const stringified = JSON.stringify(queryArgs, (key, value) => {
51-
// Translate bigint fields to a serializable value
52-
value = typeof value === 'bigint' ? { $bigint: value.toString() } : value
22+
// Use custom replacer first before applying key-sorting behavior:
23+
value = replacer ? replacer(key, value) : value
5324
// Sort the object keys before stringifying, to prevent useQuery({ a: 1, b: 2 }) having a different cache key than useQuery({ b: 2, a: 1 })
5425
value = isPlainObject(value)
5526
? Object.keys(value)
@@ -66,18 +37,21 @@ export const bigIntSafeSerializeQueryArgs: SerializeQueryArgs<any> = ({
6637
}
6738
serialized = stringified
6839
}
69-
// Sort the object keys before stringifying, to prevent useQuery({ a: 1, b: 2 }) having a different cache key than useQuery({ b: 2, a: 1 })
7040
return `${endpointName}(${serialized})`
7141
}
7242

7343
export type SerializeQueryArgs<QueryArgs, ReturnType = string> = (_: {
7444
queryArgs: QueryArgs
7545
endpointDefinition: EndpointDefinition<any, any, any, any>
7646
endpointName: string
47+
// Allows for a custom stringify replacer while keeping key-sorting behavior. e.g. for serializing bigint.
48+
replacer?: (key: string, value: any) => {}
7749
}) => ReturnType
7850

7951
export type InternalSerializeQueryArgs = (_: {
8052
queryArgs: any
8153
endpointDefinition: EndpointDefinition<any, any, any, any>
8254
endpointName: string
55+
// Allows for a custom stringify replacer while keeping key-sorting behavior. e.g. for serializing bigint.
56+
replacer?: (key: string, value: any) => {}
8357
}) => QueryCacheKey

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import {
4545
import { shallowEqual } from 'react-redux'
4646
import type { BaseQueryFn } from '../baseQueryTypes'
4747
import type { SubscriptionSelectors } from '../core/buildMiddleware/types'
48-
import { bigIntSafeSerializeQueryArgs } from '../defaultSerializeQueryArgs'
48+
import { defaultSerializeQueryArgs } from '../defaultSerializeQueryArgs'
4949
import type { UninitializedValue } from './constants'
5050
import { UNINITIALIZED_VALUE } from './constants'
5151
import type { ReactHooksModuleOptions } from './module'
@@ -761,14 +761,17 @@ export function buildHooks<Definitions extends EndpointDefinitions>({
761761
subscriptionSelectorsRef.current =
762762
returnedValue as unknown as SubscriptionSelectors
763763
}
764+
const bigIntReplacer = (_: string, value: any) =>
765+
typeof value === 'bigint' ? { $bigint: value.toString() } : value
764766
const stableArg = useStableQueryArgs(
765767
skip ? skipToken : arg,
766768
// Even if the user provided a per-endpoint `serializeQueryArgs` with
767769
// a consistent return value, _here_ we want to use the default behavior
768770
// so we can tell if _anything_ actually changed. Otherwise, we can end up
769771
// with a case where the query args did change but the serialization doesn't,
770772
// and then we never try to initiate a refetch.
771-
bigIntSafeSerializeQueryArgs,
773+
(params) =>
774+
defaultSerializeQueryArgs({ replacer: bigIntReplacer, ...params }),
772775
context.endpointDefinitions[name],
773776
name,
774777
)

0 commit comments

Comments
 (0)