I am really confused, I really thought that selectors would not run if all of his parents returned the same result.
At a time, there is 1-250 clusterMarker
selector active, each with a different prop, cluster
. Its execution is rather expensive. I made sure, that it needs to be reevaluated only if the result of any of its arguments changes.
Simplified example:
const offerState = createFeatureSelector<OfferState>('offer');
const currentCarrier = createSelector(offerState, state => state.currentCarrier);
const currentContext = createSelector(offerState, state => state.currentContext);
const currentPeriod = createSelector(offerState, state => state.currentPeriod);
const filteredCarriers = createSelector(offerState, state => state.filteredCarriers);
const wanted = createSelector(offerState, state => state.wanted);
const filteredCarriersSet = createSelector(
filteredCarriers,
carriers => new Set(carriers),
);
/**
* Only fire if the changes to state affect this context.
* `undefined` => `state.currentCarrier`
* `state.currentCarrier` => `undefined`
*/
const currentCarrierInCluster = createSelector(
currentCarrier,
currentContext,
(
currentCarrier: Carrier | null,
currentContext: AbstractMapClusterContext<Carrier> | null,
{ cluster }: { cluster: AbstractMapClusterContext<Carrier> }
) => currentContext == cluster ? currentCarrier : undefined,
);
export const clusterMarker = createSelector(
filteredCarriersSet,
currentCarrierInCluster,
currentPeriod,
wanted,
(
filteredSet,
currentCarrier,
currentPeriod,
wanted,
{ cluster }: { cluster: AbstractMapClusterContext<Carrier> }
) => {
// ... code ...
},
);
Is there a part of the documentation about setting memorization options I missed? What can I do, to make this more performant?
Response to answer:
Code:
export const clusterMarkerSelectorFactory = () => createSelector(
filteredCarriersSet,
currentCarrierInCluster,
currentPeriod,
wanted,
(
filteredSet,
currentCarrier,
currentPeriod,
wanted,
{ cluster }: { cluster: AbstractMapClusterContext<Carrier> }
) => {
// ... code ...
},
);
class Component {
constructor(
private store$: Store<OfferState>,
) { }
readonly state$ = this.cluster$.pipe(
switchMap(cluster => this.store$.select(clusterMarkerSelectorFactory(), { cluster })),
);
}
This will still retrigger for every one of them.