如何使用嵌套对象编写状态化简器
how to write state reducer with nested objects
我的redux状态树的心理模型看起来像这样:
{
selectedDepartment: 'Chemistry',
purchasesByDepartment: {
Chemistry: {
purchaseOrders: {
...
},
invoices: {
...
}
},
Biology: {
purchaseOrders: {
...
},
invoices: {
...
}
},
...(another department, etc)
}
}
这是我的减速机
const purchasesByDepartment = (state = {}, action) => {
switch (action.type) {
case RECEIVE_POS:
return Object.assign({}, state, {
[action.department]: {
purchaseOrders: action.json
// but this wipes out my invoices
}
})
case RECEIVE_INVOICES:
return Object.assign({}, state, {
[action.department]: {
invoices: action.json
// but this wipes out my purchaseOrders
}
})
default:
return state
}
}
您可以在每个部门中看到,我有一个采购订单和一个发票密钥。我正在尽力编写我的化简器,使其不会改变我的状态,但我没有运气,因为每个操作当前都会清除另一个键。
我启动两个动作:RECEIEVE_POS、RECEIVE_INVOICES。
当我的操作RECEIVE_POS被派出时,我可以使用采购订单创建一个新状态,但这会清除我的发票。
当我的操作RECEIVE_INVOICES被派出时,我可以使用发票创建一个新状态,但这会清除我的采购订单。
如何编写我的减速器,以便我可以保留我的采购订单和发票(如果它们已经存在于我的州)?
您可以先通过应用更改为部门创建新状态,然后将其合并到化简器状态中。
const purchasesByDepartment = (state = {}, action) => {
switch (action.type) {
case RECEIVE_POS:
let nextPOS = Object.assign({}, state[action.department] || {}, {
purchaseOrders: action.json
});
return Object.assign({}, state, nextPOS);
default:
return state
}
}
就我个人而言,我喜欢通过使用immutablejs
使我的整个商店不可变,这使得这样的操作(以及一堆其他事情)变得微不足道:
return state.setIn([action.department, 'purchaseOrders'], action.json]);
我使用点差运算符(表示为 ...arrayName
)来实现这一点。它是 es6,我用 babel 启用该功能。
Spread
会将数组分散到其元素中,它比 Object.assign
更易于人类阅读。
使用您的上下文,对于我的化简器中的简单场景,我只是像这样:
return {
...state,
selectedDepartment: 'Chemistry or whatever'
}
这将返回一个由状态组成的数组,加上被给定值覆盖的 selectedDepartment。
对于嵌入对象,您可以这样说:
return {
...state,
purchasesByDepartment: {
...state.purchasesByDepartment,
Chemistry: {
...state.purchasesByDepartment.Chemistry,
invoices: {
{your new invoices object comes here}
}
}
}
}
对象分布与计算的属性名称相结合帮助我解决了这个问题
case RECEIVE_POS:
return {
...state,
[action.department]: {
...state[action.department],
purchaseOrders: action.json
}
}
case RECEIVE_INVOICES:
return {
...state,
[action.department]: {
...state[action.department],
invoices: action.json
}
}
相关文章:
- 如何使用密码检测网络中的状态连接
- 使用javascript反复检查用户在facebook上的登录状态
- 无法在现有状态转换期间更新-未使用任何非法的setState()
- 使用AngularJS中的UI路由器将状态重定向到默认子状态
- 为什么使用immutableJS我的状态没有改变
- 使用纯javascript而非jquery使所选选项卡处于活动状态并保持非活动状态
- 使用按钮和媒体查询切换显示状态
- 使用api在facebook页面上发布图片或状态
- 如何在 ui-option sAjaxSource 中设置用户状态过滤器?(使用 Laravel 5 + Angular
- 使链接保持活动状态,使用 JavaScript 在单击时显示悬停效果
- 在 ASP 中处于非活动状态后使用 Session.Timeout 重定向
- 如何在AngularJS Bootstrap UI Accordion状态下使用ng显示元素
- 根据AngularJS中的登录状态,使用不同模板的相同url('/')
- 如何减少'状态'templateUrl'使用Angular Ui-Router
- 如何在ui-view状态中使用D3
- 如何摆脱这个{{用户.Id}}(花括号)在页面处于加载状态时使用
- 为什么在动态设置反应状态时使用类似数组的语法
- 只在模糊状态下使用mwl-confirm指令
- 如何触发CSS“;悬停状态”;使用Javascript
- 我的函数更新状态和使用承诺时遇到了一些问题