更新由另一个减速器管理的状态
Updating state managed by another reducer
在我的 React 应用中,我的 appReducer
管理全局内容,例如通知、用户信息等
应用程序中的一个模块是库存模块,它有自己的减速器,即 inventoryReducer
。在 redux store 中,我组合了所有的 reducer。
当用户进行库存输入时,除了处理库存交易外,我还想显示在 appReducer
中处理的屏幕通知。如何从 inventoryReducer
更新 appReducer
下的 displayNotification
的状态?
以下是我的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
}
}
这是 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
}
}
我的更新清单操作需要发送 SET_INVENTORY
和 DISPLAY_NOTIFICATION
。我正在尝试了解如何从 inventoryReducer
更新 displayNotification
,其中 displayNotification
实际上由 appReducer
.
管理
跟进 azium :
I think what you're trying to do is the wrong approach. What's stopping you from a) listening to SET_INVENTORY
in your appReducer or b) dispatch both actions from your component?
据我了解,在 Redux 中,每个 reducer 都被分配了整个状态对象的一个切片,并且它们的操作被限制在该切片中。他们不允许访问由任何其他 reducer 管理的状态切片,并且他们不应该那样做。
Redux的概念描述是,它是一个可预测状态的容器。但是当我看看我们在这个问题上试图实现的目标时,如果我们 access/modify 状态由我们的 reducer-A 中的另一个 reducer-B 管理,我认为应用程序的可预测性和可维护性会受到损害。
无需妥协任何东西或将不需要的逻辑移动到我们的组件中,我们可以实现我们需要的。
选项 1
里面appReducer
你创建了一个类型 SET_INVENTORY
来完成 DISPLAY_NOTIFICATION
的功能。对于调度类型 SET_INVENTORY
(在 appReducer
和 inventoryReducer
中)的单个操作,您可以有多个订阅。
如下所示,在 appReducer
中,如果操作类型是 SET_INVENTORY
或 DISPLAY_NOTIFICATION
,reducer 会更新键 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
}
}
选项 2
创建一个方法来耦合两个动作的调度,
假设你有一个动作
function setInventory(inventoryItem) {
return {
type: types.SET_INVENTORY,
inventoryItem
};
}
还有一个动作
function displayNotification(value) {
return {
type: types.DISPLAY_NOTIFICATION,
value,
};
}
创建一个 thunk 来连接它们:
export function notifyAndSetInventory(notify, inventoryItem) {
return dispatch => {
dispatch(displayNotification(notify));
return dispatch(setInventory(inventoryItem));
};
}
在Redux的官方文档中有一章叫做'Beyond combineReducers'。它提到了在 slice reducers 之间共享数据。
Sharing data between slice reducers
我个人更喜欢link中提到的第三种解决方案,即添加第三个自定义reducer来处理需要跨切片共享数据的“特殊”情况,然后使用reduce-reducers将新定制的减速器和原来的组合减速器结合起来(即 appReducer
+ inventoryReducer
)。
const crossSliceReducer = (state, action) => {
if (action.type === 'CROSS_SLICE_ACTION') {
// You can access both app and inventory states here
}
return state;
}
// Combine the reducers like you did before
const combinedReducer({app: appReducer, inventory: inventoryReducer});
// Add the cross-slice reducer to the root reducer
const rootReducer = reduceReducers(combinedReducer, crossSliceReducer)
在我的 React 应用中,我的 appReducer
管理全局内容,例如通知、用户信息等
应用程序中的一个模块是库存模块,它有自己的减速器,即 inventoryReducer
。在 redux store 中,我组合了所有的 reducer。
当用户进行库存输入时,除了处理库存交易外,我还想显示在 appReducer
中处理的屏幕通知。如何从 inventoryReducer
更新 appReducer
下的 displayNotification
的状态?
以下是我的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
}
}
这是 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
}
}
我的更新清单操作需要发送 SET_INVENTORY
和 DISPLAY_NOTIFICATION
。我正在尝试了解如何从 inventoryReducer
更新 displayNotification
,其中 displayNotification
实际上由 appReducer
.
跟进 azium
I think what you're trying to do is the wrong approach. What's stopping you from a) listening to
SET_INVENTORY
in your appReducer or b) dispatch both actions from your component?
据我了解,在 Redux 中,每个 reducer 都被分配了整个状态对象的一个切片,并且它们的操作被限制在该切片中。他们不允许访问由任何其他 reducer 管理的状态切片,并且他们不应该那样做。
Redux的概念描述是,它是一个可预测状态的容器。但是当我看看我们在这个问题上试图实现的目标时,如果我们 access/modify 状态由我们的 reducer-A 中的另一个 reducer-B 管理,我认为应用程序的可预测性和可维护性会受到损害。
无需妥协任何东西或将不需要的逻辑移动到我们的组件中,我们可以实现我们需要的。
选项 1
里面appReducer
你创建了一个类型 SET_INVENTORY
来完成 DISPLAY_NOTIFICATION
的功能。对于调度类型 SET_INVENTORY
(在 appReducer
和 inventoryReducer
中)的单个操作,您可以有多个订阅。
如下所示,在 appReducer
中,如果操作类型是 SET_INVENTORY
或 DISPLAY_NOTIFICATION
,reducer 会更新键 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
}
}
选项 2
创建一个方法来耦合两个动作的调度,
假设你有一个动作
function setInventory(inventoryItem) {
return {
type: types.SET_INVENTORY,
inventoryItem
};
}
还有一个动作
function displayNotification(value) {
return {
type: types.DISPLAY_NOTIFICATION,
value,
};
}
创建一个 thunk 来连接它们:
export function notifyAndSetInventory(notify, inventoryItem) {
return dispatch => {
dispatch(displayNotification(notify));
return dispatch(setInventory(inventoryItem));
};
}
在Redux的官方文档中有一章叫做'Beyond combineReducers'。它提到了在 slice reducers 之间共享数据。
Sharing data between slice reducers
我个人更喜欢link中提到的第三种解决方案,即添加第三个自定义reducer来处理需要跨切片共享数据的“特殊”情况,然后使用reduce-reducers将新定制的减速器和原来的组合减速器结合起来(即 appReducer
+ inventoryReducer
)。
const crossSliceReducer = (state, action) => {
if (action.type === 'CROSS_SLICE_ACTION') {
// You can access both app and inventory states here
}
return state;
}
// Combine the reducers like you did before
const combinedReducer({app: appReducer, inventory: inventoryReducer});
// Add the cross-slice reducer to the root reducer
const rootReducer = reduceReducers(combinedReducer, crossSliceReducer)