I am learning NGRX and i dont understand why should i use createFeatureSelector if i can do the same with a callback and createSelector.
I understand that the focus of createFeatureSelector is to be specialized in a feature but in the end, I don't see any difference.
Can someone tells me what are the benefits using createFeatureSelector over a normal callback?
interface AppState {
featureA: FeatureA;
featureB: string;
featureC: boolean;
}
interface FeatureA {
age: number;
sex: string;
address: string;
}
const state: AppState = {
featureA: {
age: 18,
sex: 'male',
address: 'bla bla bla',
},
featureB: {},
featureC: true,
};
// Common selector with a callback
export const selectFeatureA = (state: AppState) => state.featureA;
export const selectFeatureAAge = createSelector(
selectFeatureA,
(featA: FeatureA) => featA.age
);
// Feature selector that does exactly the same
export const selectFeatureA2 = createFeatureSelector<FeatureA>('featureA');
export const selectFeatureAAge2 = createSelector(
selectFeatureA2,
(featA: FeatureA) => featA.age
);
tried both and was expecting some differences.
You are right in that the do pretty much the same thing. If you take a look at the source code of
createFeatureSelectoryou can see that it callscreateSelectorin a pretty similar way you did in the question. But you also may see the differences:First of all, it has a built-in check that runs in dev mode, and shows a warning if the feature slice is not available at the time selector runs.
Secondly, the actual signature of
createFeatureSelectoris:so it does not care about the type of the root state, and it makes sense as the feature states may be loaded lazily and you may not have a type for the root state at all as it may look differently depending on what modules have been already loaded. In other words, it helps keep the modular structure of the app. And yes, you can do the same with
createSelectorpassingobjectas root state type but you need to do it explicitly, whilecreateFeatureSelectordoes it implicitly.Finally,
createFeatureSelectoraccepts a string as an argument and it is pretty common to have a constant for the feature name that then is used for bothStoreModule.forFeatureandcreateFeatureSelector.