【问题标题】:Reducer A getting actions that correspond to reducer BReducer A 获取对应于 reducer B 的动作
【发布时间】:2020-07-04 11:44:40
【问题描述】:

我在 typescript 中有一个 react 应用程序,我正在使用 redux 来构建项目。我目前有 2 个减速器,一个用于从后端获取项目列表,另一个用于对用户模型执行操作。下面是我的两个reducer,我在创建redux store时使用combinedReducers。

用户减速器:

export const userReducer: Reducer<IUserState, UserActions> = (
    state = initialUserState,
    action
) => {
    switch(action.type) {
        case UserActionTypes.GET_CURRENT_USER: {
            return {
                ...state,
                currentUser: action.currentUser
            }
        }
        case UserActionTypes.SIGN_IN_USER: {
            return {
                ...state,
                currentUser: action.currentUser
            }
        }
        default:
            return initialUserState
    }
}

ListReducer:

export const listReducer: Reducer<IListState, ListActions> = (
    state = initialListState,
    action
) => {
    switch(action.type) {
        case ListActionTypes.GET_ALL: {
            return {
                ...state,
                items: actions.items
            }
        }
        case ListActionTypes.FILTER_LIST: {
            return {
                ...state,
                items: action.items
            }
        }
        default:
            return initialListState
    }
}

组合减速器

const rootReducer = combineReducers<IAppState>({
    listState: listReducer,
    userState: userReducer
})

我遇到的问题是,当我调度一个列表操作时,该操作将在列表减速器中正确执行,但该操作也会发送给用户减速器。由于用户减速器不考虑列表操作,因此返回初始状态。如果我只调用 GET_CURRENT_USER 操作,我会得到用户的信息,但是一旦我调用 GET_ALL 操作,用户信息就会重置为 null。

【问题讨论】:

  • 对于default: 语句,您应该只返回state,而不是返回initialListStateinitialUserState
  • 嘿,成功了,谢谢@julianobrasil

标签: typescript redux


【解决方案1】:

您正在返回 default: 语句中的初始状态。试试这个:

export const userReducer: Reducer<IUserState, UserActions> = (
    state = initialUserState,
    action
) => {
    switch(action.type) {
        case UserActionTypes.GET_CURRENT_USER: {
            return {
                ...state,
                currentUser: action.currentUser
            }
        }
        case UserActionTypes.SIGN_IN_USER: {
            return {
                ...state,
                currentUser: action.currentUser
            }
        }
        default:
            return {...state}; // <= instead of initialUserState
    }
}

对另一个减速器做同样的事情。

作为建议,请尝试使用immerjs 来避免改变您的对象。当您有嵌套对象时,在对象深处使用扩展运算符变得非常难以阅读并且容易出错(很容易无意中改变您的对象)。

通过使用immerjs,您的代码变为:

import produce from "immer";

...

export const userReducer: Reducer<IUserState, UserActions> = (
    state = initialUserState,
    action
) => {
    switch(action.type) {
        case UserActionTypes.SIGN_IN_USER:
        case UserActionTypes.GET_CURRENT_USER: {
            return produce(state, draftState => {
                       draftState.currentUser: action.currentUser
                   });
        }
        default:
            return produce(state, draftState => {});
    }
}

【讨论】:

    猜你喜欢
    • 2022-01-01
    • 2020-06-18
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 2016-10-06
    • 1970-01-01
    • 2017-04-13
    相关资源
    最近更新 更多