Search code examples
javascriptreactjsreduxredux-toolkitrtk-query

Can RTK queries be used to incrementally update a single stored object across subsequent queries?


I am using a map from MapBox and after every onDragStopped, the bounds of the map are sent as {nw,ne,se,sw} coordinates to the server, where the geometry of those bounds is compared the the stored geometries of regions (counties, countries, ...). If the regions intersect the map polygon, they are returned as an array of their Ids ("AF" = Afghanistan).

Currently, I am using this approach with an RTK Query (where mapPolygon is selected from the redux store):

const allRegionsQuery = useGetAllRegionsWithinBoundsQuery(
    { bbox: mapPolygon },
    {
      skip: mapPolygon === null
    }
  );

This approach works, but because the mapPolygon is essentially always different when a user moves the map, RTK ends up storing multiple query results where the args are different but the new data may have only added one new region.

How can I fetch the intersecting regions of the map, but update the same client object with only the new regions, such that the locally stored set of regions is the union of all the query results? Can this be done exclusively with RTK Queries, or must I consider a different approach?

Ex:

localRegions = ['AF', 'BE'];
mostRecentQueryResult = ['AF', 'JP', 'AU'];

---

updatedLocalRegions = ['AF', 'BE', 'JP', 'AU']

Approaches I have read about or considered:

  1. RTK Query streaming: I have never used streaming so I am unsure how how well it applies here when the bbox is sent as an arg.
  2. I could fetch the data on each dragStopped, and when I receive the data I could take the union of it and some already stored object, and just keep updating that stored object. (This would essentially eliminate the storage benefits of RTK Queries, Is this the easiest way to go about this?)

Solution

  • Yeah, this is a situation where RTKQ is not going to help you a lot - you can still use it for fetching but will have to move the storage out into a separate slice, maybe by using extraReducers in a custom slice with your endpoint's fulfilled matcher.