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
It's not typically possible to use selectors inside of reducers, because a slice reducer only has access to its own slice of the Redux state, and most selectors expect to be given the entire Redux root state as an argument.
Reselect is useful because you can compose selectors and the memoization can prevent expensive selector code from running. The memoization can also prevent needless re renders. What you should consider is maintainable code and with reselect you can write selector logic once and re use it by composing selectors.
defaultMemoize has a default cache size of 1. This means it always recalculates when the value of an argument changes. However, this can be customized as needed with a specific max cache size (new in 4.1). defaultMemoize determines if an argument has changed by calling the equalityCheck function.
Updated: 16 February 2022
New Solution from Reselector 4.1: See detail
// selector.js const selectItemsByCategory = createSelector( [ // Usual first input - extract value from `state` state => state.items, // Take the second arg, `category`, and forward to the output selector (state, category) => category ], // Output selector gets (`items, category)` as args (items, category) => items.filter(item => item.category === category) ); // App.js const items = selectItemsByCategory(state, 'javascript'); // Another way if you're using redux: const items = useSelector(state => selectItemsByCategory(state, 'javascript'));
Updated: 6 March 2021
Solution from Reselector: See detail
// selector.js import { createSelector } from 'reselect' import memoize from 'lodash.memoize' const expensiveSelector = createSelector( state => state.items, items => memoize( minValue => items.filter(item => item.value > minValue) ) ) // App.js const expensiveFilter = expensiveSelector(state) // Another way if you're using redux: // const expensiveFilter = useSelector(expensiveSelector) const slightlyExpensive = expensiveFilter(100) const veryExpensive = expensiveFilter(1000000)
Old:
This is my approach. Creating a function with parameters and return function of reselect
.
export const selectWithValue = (CUSTOM_PARAMETER) => createSelector( selectAllDataFiltered, (data) => { console.log(CUSTOM_PARAMETER) return data[CUSTOM_PARAMETER] } ) const data = selectWithValue('myValue')(myState);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With