Skip to content
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

Question: Can I nest one selector inside result function of another selector? #360

Closed
Rastamanby opened this issue Jul 26, 2018 · 6 comments

Comments

@Rastamanby
Copy link

Hi there! Can I nest one selector inside result function of another selector? Would every instance of nested selector be memoized?
example:

const itemComputedSelector = (key) => createSelector(
   // some stuff, return computed data
)
export default createSelector(
   state => state,
   itemsSelector // return ['A', 'B', 'C'],
   (state, items) => (
      items.map((itemKey) => itemComputedSelector(itemKey)(state)
      // and some stuff with result array, and return this array
   )
)
@joedski
Copy link

joedski commented Jul 31, 2018

Technically, you can do that, but it will then always recompute on every state change since state is being passed as one parameter to check for cache invalidation.

Instead of creating a selector using key, create a selector that returns another selector that itself accepts key:

const itemKeyReifierSelector = createSelector(
  // selectors which select state slices that the computor depends on.
  state => state.path.to.dep0,
  state => state.path.to.dep1,
  selectorThatSelectsDep2,
  // and of course, the computor down here.
  (dep0, dep1, dep2) =>
    // NOTE: This computed function will change any time
    // one of the deps changes,
    (itemKey) => getItemFromDeps(itemKey, dep0, dep1, dep2)
)

export default createSelector(
  itemsSelector,
  // No need to pass in `state` directly, itemKeyReifierSelector
  // handles binding state slices to a function.
  itemKeyReifierSelector,
  // NOTE: The $ prefix is what I use to signal a derived function.
  // It is not necessary.
  (items, $itemKeyReifier) =>
    items.map($itemKeyReifier)
)

UPDATE 2019-09-30: Edited itemKeyReifierSelector to make the intention clear.

@ThinkSalat
Copy link

ThinkSalat commented Sep 30, 2019

Technically, you can do that, but it will then always recompute on every state change since state is being passed as one parameter to check for cache invalidation.

Instead of creating a selector using key, create a selector that returns another selector that itself accepts key:

const itemKeyReifierSelector = createSelector(
  // selectors which select state slices that the computor depends on.
  (dep0, dep1, dep2) =>
    // NOTE: This computed function will change any time
    // one of the deps changes,
    (itemKey) => getItemFromDeps(itemKey, dep0, dep1, dep2)
)

export default createSelector(
  itemsSelector,
  // No need to pass in `state` directly, itemKeyReifierSelector
  // handles binding state slices to a function.
  itemKeyReifierSelector,
  // NOTE: The $ prefix is what I use to signal a derived function.
  // It is not necessary.
  (items, $itemKeyReifier) =>
    items.map($itemKeyReifier)
)

This pattern doesn't work... when you call itemKeyReifierSelector(itemKey), it'll pass the first argument as the state argument. your state won't be available to the selector unless you actually pass in the state.

@joedski
Copy link

joedski commented Oct 1, 2019

The pattern does work, however the sketch that I wrote out was not clear. I have updated the sketch to show the actual intent.

@ThinkSalat
Copy link

The pattern does work, however the sketch that I wrote out was not clear. I have updated the sketch to show the actual intent.

Oh, I am seeing where I went wrong. I was calling the itemKeyReifierSelector selector in the body of my actual selector, but what you have to do is pass the selector as one of the first args to createSelector, then you'll be returned the memoized selector.

Thanks so much!

@LuisHansen
Copy link

Hey folks, I'm having a bit of trouble understanding the example you gave.
What exactly is the getItemFromDeps function you call?

@MylesWardell
Copy link

Did anybody find a solution to above? I am also getting confused about what getItemFromDeps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants