更新由另一个减速器管理的状态 [英] Updating state managed by another reducer

查看:55
本文介绍了更新由另一个减速器管理的状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 React 应用中,我的 appReducer 管理全局内容,例如通知、用户信息等.

应用程序中的一个模块是库存模块,它有自己的减速器,即inventoryReducer.在 redux store 中,我组合了所有的 reducer.

我的问题是:当用户进行库存条目时,除了处理库存事务之外,我还想显示在 appReducer 中处理的屏幕通知.如何从inventoryReducer更新appReducer下的displayNotification的状态?

以下是我的应用减速器:

import 'babel-polyfill';import * as types from '../actions/actionTypes';常量初始状态 = {显示通知:{}};导出默认值(状态 = 初始状态,动作)=>{开关(动作.类型){case types.DISPLAY_NOTIFICATION :返回 Object.assign({}, state, {显示通知:action.value})默认:返回状态}}

这是inventoryReducer:

import 'babel-polyfill';import * as types from '../actions/actionTypes';常量初始状态 = {存货: []};导出默认值(状态 = 初始状态,动作)=>{开关(动作.类型){case types.SET_INVENTORY :返回 Object.assign({}, state, {库存:action.inventoryItem})case types.DISPLAY_NOTIFICATION :返回 Object.assign({}, state, {app.displayNotification: action.value//<-- 这是我访问由 appReducer 管理的 displayNotification 的方式吗?})默认:返回状态}}

我的更新清单操作需要同时发送 SET_INVENTORY 和 DISPLAY_NOTIFICATION.我试图了解如何从inventoryReducer 更新 displayNotification,其中 displayNotification 实际上由 appReducer 管理.

解决方案

按照@azium 所说的,据我所知,在 Redux 中,每个 reducer 都分配了整个 state 对象的一个​​切片,并且它们的操作被限制在那片.他们不允许访问由任何其他 reducer 管理的状态切片,并且他们不应该这样做.

Redux 的概念描述是它是一个可预测状态的容器.但是当我查看我们在这个问题中试图实现的目标时,如果我们要访问/修改由我们的 reducer-A 中的另一个 reducer-B 管理的状态,我认为应用程序的可预测性和可维护性会受到影响.

无需妥协任何东西或将不需要的逻辑移入我们的组件中,我们就可以实现我们需要的东西.

选项 1

appReducer 内部

您创建了一个类型 SET_INVENTORY,它执行 DISPLAY_NOTIFICATION 的功能.对于分派类型 SET_INVENTORY(在 appReducer 和inventoryReducer 中)的单个操作,您可以有多个订阅.

如下图,在appReducer中,如果action类型是SET_INVENTORY或者DISPLAY_NOTIFICATION,reducer会更新keydisplayNotification.>

export default (state = initialState, action) =>{开关(动作.类型){case types.SET_INVENTORY :case types.DISPLAY_NOTIFICATION :返回 Object.assign({}, state, {显示通知:action.value})默认:返回状态}}

选项 2

创建一个方法,将两个动作的分派耦合起来,

假设你有一个动作

function setInventory(inventoryItem) {返回 {类型:types.SET_INVENTORY,库存物品};}

和另一个动作

function displayNotification(value) {返回 {类型:types.DISPLAY_NOTIFICATION,价值,};}

创建一个 thunk 将它们结合起来:

导出函数notifyAndSetInventory(notify,inventoryItem) {返回调度 =>{调度(显示通知(通知));返回调度(setInventory(inventoryItem));};}

In my React app, my appReducer manages global stuff such as notifications, user info, etc.

One of the modules in the app is the inventory module which has its own reducer i.e. inventoryReducer. And in the redux store, I combine all the reducers.

My questions is this: when a user makes an inventory entry, in addition to handling the inventory transaction, I want to display an on-screen notification which is handled in the appReducer. How do I update the state of displayNotification which is under appReducer from the inventoryReducer?

The following is my app reducer:

import 'babel-polyfill';
import * as types from '../actions/actionTypes';

const initialState = {
    displayNotification: {}
};

export default (state = initialState, action) => {

    switch (action.type) {

        case types.DISPLAY_NOTIFICATION : 
            return Object.assign({}, state, {
                displayNotification: action.value
            })

        default: return state
    }
}

And this is the inventoryReducer:

import 'babel-polyfill';
import * as types from '../actions/actionTypes';

const initialState = {
    inventory: []
};

export default (state = initialState, action) => {

    switch (action.type) {

        case types.SET_INVENTORY : 
            return Object.assign({}, state, {
                inventory: action.inventoryItem
            })

        case types.DISPLAY_NOTIFICATION : 
            return Object.assign({}, state, {
                app.displayNotification: action.value // <-- Is this how I access displayNotification which is managed by the appReducer?
            })

        default: return state
    }
}

My update inventory action needs to dispatch both SET_INVENTORY and DISPLAY_NOTIFICATION. I'm trying to understand how I can update displayNotification from inventoryReducer where displayNotification is actually managed by the appReducer.

解决方案

Following up with what @azium said, as far as I understand, in Redux each reducer is allocated a slice of the entire state object and their operations are restricted in that slice. They are not allowed to access the state slice managed by any other reducer, and they shouldn't do that.

The concept description of Redux is that it is a predictable state container. But when I look at what we are trying to achieve in this question, if we were to access/modify state managed by another reducer-B in our reducer-A, the predictability and maintainability of the app is compromised according to me.

Without compromising on anything or moving undesired logic into our components, we can achieve what we need.

Option 1

Inside appReducer

you create a type SET_INVENTORY which does what DISPLAY_NOTIFICATION does. You can have multiple subscriptions for the single action that dispatches type SET_INVENTORY (in appReducer and inventoryReducer).

As shown below, in appReducer, if the action type is either SET_INVENTORY or DISPLAY_NOTIFICATION, the reducer updates the key displayNotification.

export default (state = initialState, action) => {

    switch (action.type) {

        case types.SET_INVENTORY : 
        case types.DISPLAY_NOTIFICATION : 
            return Object.assign({}, state, {
                displayNotification: action.value
            })

        default: return state
    }
}

Option 2

Create a method that couples the dispatching of two actions,

let's say you have an action

function setInventory(inventoryItem) {
    return {
        type: types.SET_INVENTORY,
        inventoryItem
    };
}

and another action

function displayNotification(value) {
    return {
        type: types.DISPLAY_NOTIFICATION,
        value,
    };
}

create a thunk to couple them:

export function notifyAndSetInventory(notify, inventoryItem) {
    return dispatch => {
        dispatch(displayNotification(notify));
        return dispatch(setInventory(inventoryItem));
    };
}

这篇关于更新由另一个减速器管理的状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆