Reactjs 为多个组件编写单个减速器

Reactjs 为多个组件编写单个减速器,reactjs,redux,react-redux,Reactjs,Redux,React Redux,我使用mapStateToProps编写了两个类组件和一个由两个组件使用的简化程序 function mapDispatchToProps(dispatch) { return { notifyFailure(id, notify) { dispatch(notifyFailure(id, notify)); } } } 部件A减速器def: import notify from '../global/reducers/notifyReducer'; co

我使用
mapStateToProps
编写了两个类组件和一个由两个组件使用的简化程序

function mapDispatchToProps(dispatch) {
  return {
    notifyFailure(id, notify) {
      dispatch(notifyFailure(id, notify));
    }
  }
}
部件A减速器def:

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

const compAReducer = combineReducers({
    notify
});

export default compAReducer;
import notify from  '../global/reducers/notifyReducer';

const compBReducer = combineReducers({
    notify
});

export default compBReducer;
部件B减速器def:

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

const compAReducer = combineReducers({
    notify
});

export default compAReducer;
import notify from  '../global/reducers/notifyReducer';

const compBReducer = combineReducers({
    notify
});

export default compBReducer;
减速器如下所示:

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分派一个动作时,它会影响组件B的状态,反之亦然

这不是我想要的行为。我希望组件将使用相同的逻辑,但将持有不同的“状态属性”。 另一个“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));
    }
  }
}

如果愿意,也可以使用。

您可以通过给每个组件一个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));
    }
  }
}

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

最终采用了高阶减速机方法:

从“../../../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;

因此,现在状态的结构是相同的,因为行为创造者负责指导行为。

最终采用了高阶还原方法:

从“../../../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;

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

谢谢你的回答,但实际上是不起作用的。它表示两个组件仍在更新(因此,在分派操作后,它们也拥有相同的id)。另外,如果之前我希望notify的状态是一个用于显示消息的简单字符串,那么现在它是一个id为键、字符串为值的对象,它不是声明性的,而且非常奇怪。我会读更多关于它的书。。谢谢,因为数据稍微复杂一点并不意味着它不再是声明性的。它可能没有您希望的那么简单,但是用id将数据包装到对象中一点也不奇怪。您完全正确-这种方法有很多优点。但我希望状态保持简单——只是一个简单的字符串。我正试图让这一景象成为国家的一面镜子。notify的消息应该是。。只是一根线。实际上,我使用定制的高阶reduces解决了这个问题:因此,现在我可以针对该州的特定区域,而无需向其添加额外的标识符(在实际的商店级别),感谢您的回答,但实际上它不起作用。它表示两个组件仍在更新(因此,在分派操作后,它们也拥有相同的id)。另外,如果之前我希望notify的状态是一个用于显示消息的简单字符串,那么现在它是一个id为键、字符串为值的对象,它不是声明性的,而且非常奇怪。我会读更多关于它的书。。谢谢,因为数据稍微复杂一点并不意味着它不再是声明性的。它可能没有您希望的那么简单,但是用id将数据包装到对象中一点也不奇怪。您完全正确-这种方法有很多优点。但我希望状态保持简单——只是一个简单的字符串。我正试图让这一景象成为国家的一面镜子。notify的消息应该是。。只是一根线。实际上,我使用定制的高阶reduces解决了这个问题:因此现在我可以针对该州的特定区域,而无需添加额外的标识符(在实际的商店级别上)