是否可以使用 MemoizedSelector 作为 createSelector 的输入参数?

Is it possible to use MemoizedSelector as an input parameter for createSelector?

我正在尝试使用 createSelector 创建一个 MemoizedSelector。我想使用另一个 MemoizedSelector 作为输入。但是在根状态改变后,这个 selector 不会重新计算新的 selected 值。

例如我们有一个状态:

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
);

所以当我们 select 名字并在 reducer 中更改它时:

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

我们在日志中看不到 "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;
}

在你的减速器中,试试这个:

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