diff --git a/packages/toolkit/src/query/react/buildHooks.ts b/packages/toolkit/src/query/react/buildHooks.ts index 249df6b071..702652df2a 100644 --- a/packages/toolkit/src/query/react/buildHooks.ts +++ b/packages/toolkit/src/query/react/buildHooks.ts @@ -39,11 +39,7 @@ import type { TSHelpersNoInfer, TSHelpersOverride, } from '@reduxjs/toolkit/query' -import { - defaultSerializeQueryArgs, - QueryStatus, - skipToken, -} from '@reduxjs/toolkit/query' +import { QueryStatus, skipToken } from '@reduxjs/toolkit/query' import type { DependencyList } from 'react' import { useCallback, @@ -1644,17 +1640,7 @@ export function buildHooks({ subscriptionSelectorsRef.current = returnedValue as unknown as SubscriptionSelectors } - const stableArg = useStableQueryArgs( - skip ? skipToken : arg, - // Even if the user provided a per-endpoint `serializeQueryArgs` with - // a consistent return value, _here_ we want to use the default behavior - // so we can tell if _anything_ actually changed. Otherwise, we can end up - // with a case where the query args did change but the serialization doesn't, - // and then we never try to initiate a refetch. - defaultSerializeQueryArgs, - context.endpointDefinitions[endpointName], - endpointName, - ) + const stableArg = useStableQueryArgs(skip ? skipToken : arg) const stableSubscriptionOptions = useShallowStableValue({ refetchOnReconnect, refetchOnFocus, @@ -1764,12 +1750,7 @@ export function buildHooks({ QueryDefinition, Definitions > - const stableArg = useStableQueryArgs( - skip ? skipToken : arg, - serializeQueryArgs, - context.endpointDefinitions[endpointName], - endpointName, - ) + const stableArg = useStableQueryArgs(skip ? skipToken : arg) type ApiRootState = Parameters>[0] @@ -2053,17 +2034,7 @@ export function buildHooks({ usePromiseRefUnsubscribeOnUnmount(promiseRef) - const stableArg = useStableQueryArgs( - options.skip ? skipToken : arg, - // Even if the user provided a per-endpoint `serializeQueryArgs` with - // a consistent return value, _here_ we want to use the default behavior - // so we can tell if _anything_ actually changed. Otherwise, we can end up - // with a case where the query args did change but the serialization doesn't, - // and then we never try to initiate a refetch. - defaultSerializeQueryArgs, - context.endpointDefinitions[endpointName], - endpointName, - ) + const stableArg = useStableQueryArgs(options.skip ? skipToken : arg) const refetch = useCallback( () => refetchOrErrorIfUnmounted(promiseRef), diff --git a/packages/toolkit/src/query/react/useSerializedStableValue.ts b/packages/toolkit/src/query/react/useSerializedStableValue.ts index 95bc62af78..5a5d9f936f 100644 --- a/packages/toolkit/src/query/react/useSerializedStableValue.ts +++ b/packages/toolkit/src/query/react/useSerializedStableValue.ts @@ -1,31 +1,17 @@ import { useEffect, useRef, useMemo } from 'react' -import type { SerializeQueryArgs } from '@reduxjs/toolkit/query' -import type { EndpointDefinition } from '@reduxjs/toolkit/query' +import { copyWithStructuralSharing } from '@reduxjs/toolkit/query' -export function useStableQueryArgs( - queryArgs: T, - serialize: SerializeQueryArgs, - endpointDefinition: EndpointDefinition, - endpointName: string, -) { - const incoming = useMemo( - () => ({ - queryArgs, - serialized: - typeof queryArgs == 'object' - ? serialize({ queryArgs, endpointDefinition, endpointName }) - : queryArgs, - }), - [queryArgs, serialize, endpointDefinition, endpointName], +export function useStableQueryArgs(queryArgs: T) { + const cache = useRef(queryArgs) + const copy = useMemo( + () => copyWithStructuralSharing(cache.current, queryArgs), + [queryArgs], ) - const cache = useRef(incoming) useEffect(() => { - if (cache.current.serialized !== incoming.serialized) { - cache.current = incoming + if (cache.current !== copy) { + cache.current = copy } - }, [incoming]) + }, [copy]) - return cache.current.serialized === incoming.serialized - ? cache.current.queryArgs - : queryArgs + return copy }