为多个组件编写一个 Reducer

Writing a single Reducer for multiple Componenets

我编写了 2 个 class 组件,以及一个供两个组件使用的减速器 mapStateToProps

组件 A 减速器定义:

import notify from '../global/reducers/notifyReducer';

const compAReducer = combineReducers({
    notify
});

export default compAReducer;

组件 B 减速器定义:

import notify from  '../global/reducers/notifyReducer';

const compBReducer = combineReducers({
    notify
});

export default compBReducer;

reducer 看起来像这样:

import * as types from '../../../actions/actionTypes';

export default function notifyReducer(state = {}, action) {
    switch (action.type) {
        case types.NOTIFY_SUCCESS:
        case types.NOTIFY_FAILURE:
            return action.notify;
        case types.NOTIFY_NULL:
            return {};
        default:
            return state;
    }
}

问题是当组件A dispatch 一个动作时,它会影响组件B 的状态,反之亦然。

这不是我想要的行为。我希望该组件将使用相同的逻辑,但会持有不同的 "state property"。 一个不同的 "notify" 实例。

是否可能,或者我是否必须复制减速器?

非常感谢。我还在学习 React-Redux。

您可以通过给每个组件一个 ID 来命名您的状态。

export function notifyReducer(state = {}, action) {
  switch (action.type) {
        case types.NOTIFY_SUCCESS:
        case types.NOTIFY_FAILURE:
            return { ...state, [action.id]: action.notify };
        case types.NOTIFY_NULL:
            return { ...state, [action.id]: {} };
        default:
            return state;
    }
}

然后您需要做的就是确保您的组件包含 id 属性 及其分派的每个操作。

根据您的应用程序,可能已经有一个逻辑 ID 与您的组件的每个实例相关联,否则您可以在构造函数中生成一个随机 ID。

import uid from 'uid';

constructor() {
  super(this);
  this.id = uid();
}

那么您的每个动作创建者都应该接受 id 作为参数。

function notifyFailure(id, notify) {
  return { id, type: types.NOTIFY_FAILURE, notify }
}

最后,你需要在 mapDispatchToProps.

时传递 ID
function mapDispatchToProps(dispatch) {
  return {
    notifyFailure(id, notify) {
      dispatch(notifyFailure(id, notify));
    }
  }
}

如果您愿意,也可以使用 bindActionCreators

最终采用高阶减速器方法:

You can read about it here

从“../../../actions/actionTypes”导入 * 作为类型;

export default function createNotifyReducerWithPageType(pageType = '') {
    return function notifyReducer(state = '', action) {
        switch (action.type) {
            case types.NOTIFY_SUCCESS + `_${pageType}`:
            case types.NOTIFY_FAILURE + `_${pageType}`:
                return action.notify;
            case types.NOTIFY_NULL:
                return {};
            default:
                return state;
        }
    }
}

动作创作者:

export function notifySuccess(notify, type) {
    return {
        type: types.NOTIFY_SUCCESS + type,
        notify
    }
}

export function notifyFailure(notify, type) {
    return {
        type: types.NOTIFY_FAILURE + type,
        notify
    }
}

减速器:

import createNotifyReducerWithPageType from '../global/reducers/notifyReducer';

const compA = combineReducers({
    notify: createNotifyReducerWithPageType('_compA')
});

export default compA;

第二个:

import createNotifyReducerWithPageType from '../global/reducers/notifyReducer';

const compB = combineReducers({
    notify: createNotifyReducerWithPageType('_compB')
});

export default compB;

所以现在状态的结构是相同的,因为动作创建者负责指导行为。