3

I have an endpoint which accepts a parameter and I'm trying to access the cached data using endpoint.select() in a redux slice. The problem is i cant figure out how to pass in the cache key. I've done the following:

export const selectProductsResult = (storeId) =>
   storeApi.endpoints.listProductsByStore.select(storeId);

This works fine if I use it within a component like this:

const currentStoreProducts = useSelector(selectProductResult(currentStoreId))

What I don't understand is how I can use this in another selector, for example this does not work:

 const selectCurrentProducts = createSelector((selectCurrentStoreId), currentStoreId 
     => selectProductResult(currentStoreId)

If I try to use this in a component like so:

const currentProducts = useSelector(selectCurrentProducts)

The value obtained is a memoized function. I've played around quite a bit and can't seem to build the desired selector.

DannyMoshe
  • 6,023
  • 4
  • 31
  • 53
  • 2
    I just wanted to add: if you want to use this in a component anyways, it's most likely a better idea to use the `useQuery` hooks for that data instead of `useSelector` with a selector from the endpoint. If you want to abstract it out, move it into a custom hook. – phry Mar 11 '22 at 08:19
  • I'm migrating a large number of selectors over to rtk-query, the goal was to supply existing selectors but just swap out the api layer as a start, but there are some dependent queries. Sounds like most of them will need to be converted to hooks. – DannyMoshe Mar 11 '22 at 09:09

1 Answers1

3

The call to someEndpoint.select() generates a new selector function that is specialized to look up the data for that cache key. Loosely put, imagine it looks like this:

const createEndpointSelector = (cacheKey) => {
  return selectorForCacheKey = () => {
    return state.api.queries['someEndpointName'][cacheKey];
  }
}

const selectDataForPikachu = createEndpointSelector('pikachu');

So, you need to call someEndpoint.select() with the actual cache key itself, and it returns a new selector that knows how to retrieve the data for that cache key:

const selectDataForPikachu = apiSlice.endpoints.getPokemon.select('pikachu');

// later, in a component
const pikachuData = useSelector(selectDataForPikachu);
markerikson
  • 63,178
  • 10
  • 141
  • 157
  • So in my case 'pikachu' is a dynamic value which is coming from another endpoint.select(). Is there any way to create a selector which returns the data using the result of another endpoint.select() function as its cache key? I know i can do this in a hook, but would like to plug data into existing selectors. – DannyMoshe Mar 11 '22 at 05:02
  • I'm not sure that's entirely feasible atm - you'd have to pass in `selectOtherEndpointData` as an "input selector" and call `thisEndpoint.select()` inside the output function... but that selector in turn requires the _entire_ Redux root state as its argument, which means that this selector wouldn't memoize correctly ever. – markerikson Mar 16 '22 at 17:33
  • 1
    @DannyMoshe, were you able to send dynamic value to the `select` method? – JPS Mar 23 '23 at 19:58