可以将MemoizedSelector用作createSelector的输入参数吗?

时间:2019-07-13 13:55:56

标签: angular typescript ngrx memoization ngrx-store

我正在尝试使用createSelector创建一个MemoizedSelector。我想使用另一个MemoizedSelector作为输入。但是,更改根状态后,该选择器不会重新计算新的选定值。

例如我们有一个状态:

const initialState: RootState = {
  user: {
    name: {
      first: 'John',
      last: 'Doe',
    },
  },
};

和一系列减速器:

const userSelector = (state: RootState) => state.user;

const nameSelector : MemoizedSelector<RootState, UserName> = createSelector(
  userSelector,
  (user: User) => user.name
);

const lastNameSelector : MemoizedSelector<RootState, string>  = createSelector(
  nameSelector,
  (userName: UserName) => userName.last
);

因此,当我们选择名字并在化简器中对其进行更改时:

this.store$.select(lastNameSelector).subscribe(it => console.log(it));
this.store$.dispatch({type:'CHANGE_LAST_NAME', payload: 'Brown'});

我们在日志中看不到“棕色”。

我可以使它使用clean函数:

const lastNameSelector = (state: RootState) => state.user.name.last;

但我想利用记忆功能,并且在更改任何其他状态参数时不要重新计算用户的姓氏。 我该怎么做才能使其正常工作?

示例应用:https://github.com/vadim-shb/ngrx-issue

更新:

问题出在减速器中:

export function userReducer(state: UserData = initialState, action: any) {
  if (action.type === 'CHANGE_LAST_NAME') {
    let result = {
      ...state
    };
    result.name.last = action.payload;
    return result;
  }
  return state;
}

1 个答案:

答案 0 :(得分:1)

在减速器中,尝试以下操作:

if (action.type === 'CHANGE_LAST_NAME') {
    let result = {
      ...state,
      name: {
        ...state.name,
        last: action.payload
      }
     }
    return result;
  }