Skip to content

Question: Rtk Endpoint Hook Called In Component Loop #4710

Closed
@rdeanmcdonald

Description

@rdeanmcdonald

Hi folks! I have an RTK question, hope this is the right place to ask it. I've got an RTK endpoint definition that looks something like:

export const apiSlice = createApi({
    baseQuery: fetchBaseQuery({
        ...
    }),
    tagTypes: [
        "Customers",
    ],
    endpoints: (builder) => ({
        getCustomersByDriverIds: builder.query<
            Customer[],
            GetCustomersByDriverIdsParams
        >({
            query: ({ driverIds }) =>
                `/customers?${driverIds
                    .map((did) => `driverIds=${did}`)
                    .join("&")}`,
            providesTags: ["Customers"]
        }),
    })
});

I have a react component that allows you to select/deselect multiple customers. Select/Deselect/Bulk Select/Bulk Deselect.

Its works well with the above RTK definition, using something like this in the component:

    const selectedTerritoryDriverIds = useAppSelector(selectedTerritoriesSelector);
    const { data: customersByDriverId } = useGetCustomersByDriverIdsQuery(
        {driverIds: selectedTerritoryDriverIds},
    );

The problem is, the caching isn't working well.
E.g. if you select all customers, it makes a query/cache entry for:

/customers?driverId=123&driverId=456&driverId=789&...

And lets say I deselect a single customer (e.g. customer 123), then this query is made:

/customers?driverId=456&driverId=789&...

So another query, and another cache entry with data that all was already fetched.

I've been trying to get this excessive query/caching to be better, but am struggling. I keep thinking there must be a way this is supposed to be done with RTK but I can't find anything!

Any pointers would be very much appreciated!

Some things I've thought of doing but either can't or it's really ugly:

  1. Make a call to /customers?driverId=??? for 1 driver at a time, in a loop, but I can't use the hook inside a loop in the component.
  2. Use the lazyQuery, then I can do it in a loop, but now invalidation doesn't trigger component re-rendering as I'd like.
  3. Create a separate redux slice, bypassing RTK to take care of this logic. (would be fine but just keep thinking RTK would already have a pattern for this type of use case that I should be using)
  4. Use queryFn instead of query in RTK, where I can check the endpoint state. But then handling invalidation is impossible (unless I'm missing something, I don't see any invalidating state in the rtk state)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions