Skip to content

Custom equality check for determining argument changes in useQuery from rtk-query/react #1768

@kasper573

Description

@kasper573

This issue is referring to how stableArg is determined in buildHooks.ts/useQuerySubscription:

const stableArg = useShallowStableValue(skip ? skipToken : arg)

The problem

In the examples below, useQuery is pseudo code to refer to an arbitrary query hook generated by @reduxjs/toolkit/query/react.

The current implementation performs a shallow equality check to allow the hook consumer to pass in inline objects without having to manually memoize these:

useQuery({foo: 123, bar: "baz"}) // This is stable

However, if the consumer wants to use a nested object, the shallow equality will not be able to understand that no change has been made:

useQuery({nested: {foo: 123, bar: "baz"}}); // This is not stable

To work around this the consumer would have to manually memoize the query argument, which easily becomes very verbose in larger projects with lots of queries and views, requiring an extra statement per query.

const stableArg = useMemo(() => ({nested: {foo: 123, bar: "baz"}}), []);
useQuery(stableArg);

Suggested solution

I suggest to provide the option to use any kind of equality checking:

useQuery({nested: {foo: 123, bar: "baz"}}, {equalsFn: deepEquals}); // This is stable

In the above example, useQuery would determine whether the argument has changed by calling the provided deepEquals function, instead of the default shallowEquals function.

Additionally, a central configuration could be provided, to modify the default equality checking function for all queries:

createApi({
  baseQuery: ...,
  endpoints: ...,
  useQueryArgEqualsFn: deepEquals
})

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions