我有一个用于搜索的 reducer ,并意识到它需要用于多个不相关的搜索组件。因此,在浏览 Redux 文档时,我发现了高阶 reducer ( http://redux.js.org/docs/recipes/reducers/ReusingReducerLogic.html#customizing-behavior-with-higher-order-reducers )(ngrx 中的元 reducer )的概念,并使用它来创建我的搜索 reducer 的 2 个“实例”。然后我在同一文档中发现,这似乎适用于选择器,但实际上存在内存问题( http://redux.js.org/docs/recipes/ComputingDerivedData.html#accessing-react-props-in-selectors )。那篇文章引用了一个名为“mapStateToProps”的函数,它似乎是将存储数据连接到组件的 React 特定方式(如果我理解正确的话......)。
ngrx 中是否有等效项,或者是否有其他方法来创建这些选择器以与 reducer 的不同实例一起使用?
下面是一个基于我想要完成的 ngrx 示例应用程序的温和设计的示例:
reducers/searchReducer.ts:
export interface State {
ids: string[];
loading: boolean;
query: string;
};
const initialState: State = {
ids: [],
loading: false,
query: ''
};
export const createSearchReducer = (instanceName: string) => {
return (state = initialState, action: actions.Actions): State => {
const {name} = action; // Use this name to differentiate instances when dispatching an action.
if(name !== instanceName) return state;
switch (action.type) {
//...
}
}
}
reducers/index.ts:
export interface State {
search: fromSearch.State;
}
const reducers = {
search: combineReducers({
books: searchReducer.createReducer('books'),
magazines: searchReducer.createReducer('magazines')
}),
}
export const getSearchState = (state: State) => state.search;
// (1)
export const getSearchIds = createSelector(getSearchState, fromSearch.getIds);
我相信上面的 getSearchIds 选择器需要能够以某种方式指定它正在访问的搜索 reducer 的实例。 (奇怪的是,在我的代码中,它似乎可以工作,但我不确定它如何知道要选择哪个,我认为它存在 Redux 文档中讨论的内存问题)。
最佳答案
虽然 Kevin 的回答对于我给出的人为代码示例来说是有意义的,但如果每个 reducer “实例”具有许多属性或者如果您需要许多“实例”,那么肯定会存在维护问题。在这些情况下,您最终会在单个 reducer 上得到许多准重复的属性(例如“bookIds”、“magazineIds”、“dvdIds”、“microficheIds”等)。
考虑到这一点,我回到了 Redux 文档,并按照它查看了选择器的常见问题解答,特别是 How Do I create a Selector That Takes an Argument .
根据这些信息,我将其放在一起:
reducers/index.ts:
export const getBookSearchState = (state: State) => state.search;
export const getMagazineSearchState = (state: State) => state.search;
// A function to allow the developer to choose the instance of search reducer to target in their selector.
export const chooseSearchInstance = (instance: string): ((state: State) => searchReducer.State) => {
switch(instance) {
case 'books': {
return getBookSearchState;
}
case 'magazines': {
return getMagazineSearchState;
}
}
}
// Determines the instance based on the param and returns the selector function.
export const getSearchIds = (instance: string) => {
const searchState = chooseSearchInstance(instance);
return createSelector(searchState, state => state.ids);
}
在某些您知道要使用的 reducer 的组件中:
//...
class SearchComponent {
@Input()
searchType: string = 'books';
ids: Observable<number>;
constructor(private store: Store<fromRoot.State>) {
this.store.select(fromRoot.getSearchIds(searchType));
}
}
关于angular - NGRX reducer 多个实例的选择器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45108947/