EDIT
I slept and dreamed (seriously haha) with a simple (but perhaps still unnecessary) solution for this case. You must return the primitive type of the filter result so that you can JSON.stringify() it and JSON.parse() on the second selector. The following test package passes:
const state = { list: [ { id: 1, active: true }, { id: 2, active: false }, { id: 3, active: false }, { id: 4, active: false } ] } const getFilteredListIds = createSelector( (state) => JSON.stringify(state.list.filter((object) => !!object.active)), (filteredList) => JSON.parse(filteredList).map((object) => object.id) ) expect(getFilteredListIds.recomputations()).toEqual(0) expect(getFilteredListIds(state)).toEqual([1]) expect(getFilteredListIds.recomputations()).toEqual(1) expect(getFilteredListIds(state)).toEqual([1]) expect(getFilteredListIds.recomputations()).toEqual(1) const newState = { list: [ ...state.list, { id: 5, active: false }
However, depending on your use case, it may be slower than a filter for each call. If you test this performance, share with us.
FIRST MAIL
As I said in the comments , the way you did this makes createSelector useless.
const state = { list: [ { id: 1, active: true }, { id: 2, active: false }, { id: 3, active: false }, { id: 4, active: false } ] } const getFilteredListIds = createSelector( (state) => state.list.filter((object) => !!object.active), (filteredList) => filteredList.map((object) => object.id) ) expect(getFilteredListIds.recomputations()).toEqual(0) expect(getFilteredListIds(state)).toEqual([1]) expect(getFilteredListIds.recomputations()).toEqual(1) expect(getFilteredListIds(state)).toEqual([1]) expect(getFilteredListIds.recomputations()).toEqual(1)
First, I made some adaptations to solve this first problem.
const state = { list: [ { id: 1, active: true }, { id: 2, active: false }, { id: 3, active: false }, { id: 4, active: false } ] } const getList = (state) => state.list
Now your question is correct:
Is it possible to get only a new object, if there are changes in the objects or the filtered list?
What do you want, is that right?
const newState = { list: [ ...state.list, { id: 5, active: false }
But the last line will not work, because recomputations() will be 2.
The only way I can see this is to make a memoized filteredList part of your state, but it can be weird.