我正在学习 NGRX,我不明白为什么我应该使用
createFeatureSelector
如果我可以通过回调和 createSelector
做同样的事情。
我知道 createFeatureSelector 的重点是专门针对某个功能,但最终我没有看到任何区别。
有人可以告诉我使用
createFeatureSelector
比普通回调有什么好处吗?
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
);
两者都尝试过,并期待一些差异。
你是对的,他们做的事情几乎是一样的。如果您查看 createFeatureSelector
的
源代码,您可以看到它以与您在问题中所做的非常相似的方式调用
createSelector
。但您也可能会看到差异:
首先,它有一个在开发模式下运行的内置检查,如果功能切片在选择器运行时不可用,则会显示警告。
其次,
createFeatureSelector
的实际签名是:
function createFeatureSelector<T>(featureName: string): MemoizedSelector<object, T>;
所以它不关心根状态的类型,这是有道理的,因为功能状态可能会延迟加载,并且您可能根本没有根状态的类型,因为根据模块的不同,它看起来可能有所不同已经加载。换句话说,它有助于保持应用程序的模块化结构。是的,您可以通过
createSelector
将 object
作为根状态类型传递,但您需要显式执行此操作,而 createFeatureSelector
则隐式执行此操作。
最后,
createFeatureSelector
接受一个字符串作为参数,并且特征名称常量很常见,然后用于StoreModule.forFeature
和createFeatureSelector
。