New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Help - How to memoize RTKQ selector with dynamic argument from state, not selector arg. #4362
Comments
More like this. const createInventorySelector = createSelector(
selectGameId,
(id) => api.endpoints.listInventoryForGame.select(id),
);
export const selectInventory = createSelector(
(state: RootState) => state,
createInventorySelector,
(state: RootState, inventorySelector) => inventorySelector(state),
);
const inventory = selectInventory(state); |
Ahh ok, thank you for the correction. Unfortunately it's still not being memoized correctly, as the number of recomputations is the same as before (I'm using checkSelector from "reselect-tools"). It looks like it's recomputing after every dispatched action. |
Yes, a selector that has (In fact, Reselect ought to be warning you about that in dev mode.) |
Yeah okay, good to know. I was wondering if it was even possible. I suppose it's probably not necessary, given that the selector isn't doing any heavy computation? If that's the case, it might be worth adding a caveat to the Do you have any recommendations for a better solution, or do I just leave that selector as is and handle memoization on the selectors that depend on that selector? |
I tried something like this which was recomputed much less, but it doesn't seem ideal (accessing rtkq implementation details?): export const selectInventory = createSelector(
(state: RootState) => state.api.queries,
selectGameId,
(queries, gameId) => {
return queries[`listInventoryForGame("${gameId}")`];
},
); |
The question is also at which selector you are looking here. The example I had above contains multiple selectors:
While Realistically, you can rewrite my example up there to const createInventorySelector = createSelector(
selectGameId,
(id) => api.endpoints.listInventoryForGame.select(id),
);
const selector = createInventorySelector(state)
const inventory = selector (state); and both |
Query selectors are created internally using That said, it feels like this might be easier if you skip the const selectInventory = (state: RootState) => {
const id = selectGameId(state);
const inventorySelector = api.endpoints.listInventoryForGame.select(id)
return inventorySelector(state);
} or if you wanted to save on the slight cost of generating the per-ID selectors: const selectorsForIds = {};
const selectInventory = (state: RootState) => {
const id = selectGameId(state);
if (!(id in selectorsForIds)) {
selectorsForIds[id] = api.endpoints.listInventoryForGame.select(id)
}
const inventorySelector = selectorsForIds[id];
return inventorySelector(state);
} |
Right okay, that makes sense. I like the example of not using createSelector, as it's more explicit that it won't be memoized since it relies on |
Looking for help on this, as I can't wrap my head around how to get a proper memoized selector using RTKQ... The selector needs the
gameId
from store state, not a selector arg.This is what I have right now that isn't memoizing:
I know
state => state
isn't good, but I'm trying to follow the example here https://redux-toolkit.js.org/rtk-query/usage/usage-without-react-hooks#memoization, and don't see how to do it otherwise.Thanks.
The text was updated successfully, but these errors were encountered: