when should i use createFeatureSelector (NGRX) over a callback

28 Views Asked by At

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.

1

There are 1 best solutions below

0
Shlang On BEST ANSWER

You are right in that the do pretty much the same thing. If you take a look at the source code of createFeatureSelector you can see that it calls createSelector in 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 createFeatureSelector is:

function createFeatureSelector<T>(featureName: string): MemoizedSelector<object, T>;

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 createSelector passing object as root state type but you need to do it explicitly, while createFeatureSelector does it implicitly.

Finally, createFeatureSelector accepts a string as an argument and it is pretty common to have a constant for the feature name that then is used for both StoreModule.forFeature and createFeatureSelector.