Use reselect selector with parameters

2019-06-15 05:23发布

How do I pass additional parameters to combined selectors? I am trying to

• Get data

• Filter data

• Add custom value to my data set / group data by myValue

export const allData = state => state.dataTable
export const filterText = state => state.filter.get('text')

export const selectAllData = createSelector(
  allData,
  (data) => data
)

export const selectAllDataFiltered = createSelector(
  [ selectAllData, filterText ],
  (data, text) => {
    return data.filter(item => {
      return item.name === text
    })
  }
)

export const selectWithValue = createSelector(
  [ selectAllDataFiltered ],
  (data, myValue) => {
    console.log(myValue)
    return data
  }
)

let data = selectWithValue(state, 'myValue')

console.log(myValue) returns undefined

3条回答
小情绪 Triste *
2楼-- · 2019-06-15 06:03

The answer to your questions is detailed in an FAQ here: https://github.com/reactjs/reselect#q-how-do-i-create-a-selector-that-takes-an-argument

In short, reselect doesn't support arbitrary arguments passed to selectors. The recommended approach is, instead of passing an argument, store that same data in your Redux state.

查看更多
一纸荒年 Trace。
3楼-- · 2019-06-15 06:05

Another option:

const parameterizedSelector = (state, someParam) => createSelector(
  [otherSelector],
  (otherSelectorResult) => someParam + otherSelectorResult
);

And then use like

const mapStateToProps = state => ({
  parameterizedSelectorResult: parameterizedSelector(state, 'hello')
});

I am not sure about memoization/performance in this case though, but it works.

查看更多
相关推荐>>
4楼-- · 2019-06-15 06:12

what about returning a function from selector? getFilteredToDos is an example for that

// redux part
const state = {
  todos: [
    { state: 'done',     text: 'foo' },
    { state: 'time out', text: 'bar' },
  ],
};

// selector for todos
const getToDos = createSelector(
  getState,
  (state) => state.todos,
);

// selector for filtered todos
const getFilteredToDos = createSelector(
  getToDos,
  (todos) => (todoState) => todos.filter((toDo) => toDo.state === todoState);
);

// and in component
const mapStateToProps = (state, ownProps) => ({
  ...ownProps,
  doneToDos: getFilteredToDos()('done')
});
查看更多
登录 后发表回答