skip to Main Content

This is an example from reselect documents

const selectItemsByCategory = createSelector(
  [
    state => state.items,
    (state, category) => category
  ],
  (items, category) => items.filter(item => item.category === category)
)

usage on react

  const myitems = useSelector(
    (state) => selectItemsByCategory(state, 'CatName')
  )

My question is, how can I pass more than one parameter?

const selectChildItemByNameAndCategoryName = createSelector(
  [
    selectItemsByCategory
    (state, childName) => childName
  ],
  (categories, childName) => categories.filter... using childName form results of selectItemsByCategory
)

how can I use it?

  const myitems = useSelector(
    (state) => selectChildItemByNameAndCategoryName(state, 'CatName', 'childName')
  )

2

Answers


  1. createSelector always forwards all arguments to all input selectors.

    import { createSelector } from 'reselect';
    
    const selectItemsByCategory = createSelector(
      [
        (state) => state.items,
        (state, category, childName) => {
          console.log('🚀 ~ file: index.ts:7 ~ category:', category);
          console.log('🚀 ~ file: index.ts:7 ~ childName:', childName);
          return category;
        },
      ],
      (items, category) => items.filter((item) => item.category === category),
    );
    
    const selectChildItemByNameAndCategoryName = createSelector(
      [
        selectItemsByCategory,
        (state, category, childName) => {
          console.log('🚀 ~ file: index.ts:19 ~ category:', category);
          console.log("🚀 ~ file: index.ts:19 ~ childName:", childName)
          return childName;
        },
      ],
      (items, childName) => items.filter((item) => item.childName === childName),
    );
    
    const data = selectChildItemByNameAndCategoryName(
      {
        items: [
          { category: 'a', childName: 'x' },
          { category: 'a', childName: 'y' },
          { category: 'b', childName: 'x' },
        ],
      },
      'a',
      'x',
    );
    console.log(data);
    

    Output:

    🚀 ~ file: index.ts:7 ~ category: a
    🚀 ~ file: index.ts:7 ~ childName: x
    🚀 ~ file: index.ts:19 ~ category: a
    🚀 ~ file: index.ts:19 ~ childName: x
    [ { category: 'a', childName: 'x' } ]
    
    Login or Signup to reply.
  2. In your case you can simply just do this:

    const selectChildItemByNameAndCategoryName = createSelector(
          [
            selectItemsByCategory,
            (state, childName) => childName,
            (state, childName, catName) => catName
          ],
          (categories, childName, catName) => categories.filter... using childName form results of selectItemsByCategory
        )
    

    So in you component you can position the arguments in a similar order:

    const myitems = useSelector((state) => selectChildItemByNameAndCategoryName(state, 'childName', 'CatName'))
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search