I would make a selector creator that will curry the unit
parameter. I am assuming that unit comes from props and the component wants to re calculate if unit changes or history changes:
const getNodeHistory = (state) => state.session.nodeHistory;
export const createSelectNodeHistory = (unit) =>// curry unit parameter
createSelector([getNodeHistory], (history) =>
history.filter((h) => h.unit === unit)
);
const Component = ({ unit }) => {
//memoize the selector (re create when unit changes)
// here memoization of unit parameter is done in component
// so each component has their own memoized selector
const selectNodeHistory = React.useMemo(
() => createSelectNodeHistory(unit),
[unit]
);
const nodeHistory = useSelector(selectNodeHistory);
};
In that example each component will have their own selector. You could also move the memoization logic to the code creating the selector but if you render multiple components with different unit values using this selector then nothing will be memoized because they all share the same selector.
//moved memoizing to create selector, memoization or unit is shared
// for all components calling createSelectNodeHistory
export const createSelectNodeHistory = createSelector(
(unit) => unit,
(unit) =>
createSelector([getNodeHistory], (history) =>
history.filter((h) => h.unit === unit)
)
);
const Component = ({ unit }) => {
//create memoized selector, will be re created when
// unit changes. Because memoization of unit is shared by
// all components nothing will be memoized when you do
// <Component unit={1} /><Component unit={2} />
const selectNodeHistory = createSelectNodeHistory(unit);
const nodeHistory = useSelector(selectNodeHistory);
};
Now to address our problem; when nodeHistory changes but that change did not affect history.filter you could memoize the filter result like in this answer in your situation the code would look like this:
const createMemoizedArray = () => {
const memArray = defaultMemoize((...array) => array);
return (array) => memArray.apply(null, array);
};
export const createSelectNodeHistory = createSelector(
(unit) => unit,
(unit) => {
const memArray = createMemoizedArray();
return createSelector([getNodeHistory], (history) =>
memArray(history.filter((h) => h.unit === unit))
);
}
);
Or like this if each component needs their own memomized selector:
export const createSelectNodeHistory = (
unit // curry unit parameter
) => {
const memArray = createMemoizedArray();
return createSelector([getNodeHistory], (history) =>
memArray(history.filter((h) => h.unit === unit))
);
};