Javascript 如何在不使用扩展运算符的情况下更改Redux状态的子片
我需要更新我的状态的一个片段中的一个片段,而不更新整个片段;只有子切片。我见过其他人联合使用减缩器来实现这一点,但我还没有弄清楚如何在我的项目中实现这一点。Redux.js.org将此显示为另一种方法:Javascript 如何在不使用扩展运算符的情况下更改Redux状态的子片,javascript,redux,Javascript,Redux,我需要更新我的状态的一个片段中的一个片段,而不更新整个片段;只有子切片。我见过其他人联合使用减缩器来实现这一点,但我还没有弄清楚如何在我的项目中实现这一点。Redux.js.org将此显示为另一种方法: function updateVeryNestedField(state, action) { return { ....state, first : { ...state.first, second : {
function updateVeryNestedField(state, action) {
return {
....state,
first : {
...state.first,
second : {
...state.first.second,
[action.someId] : {
...state.first.second[action.someId],
fourth : action.someValue
}
}
}
}
}
不幸的是,我的项目是用javascript编写的。如果没有spread操作符,我如何用vanilla javascript复制它?我尝试了使用
对象的一些变体。分配
,但无法使其工作。如您所述,您可以使用对象。分配
代替排列:
{...state, x: 1}
应该给你和我一样的结果
Object.assign({}, state, {x: 1})
请注意,空对象是对象的第一个参数。分配。这样做的目的是将值从state
复制到新的空对象中,然后将值从{first:1}
复制到新对象中
例如:
var a = { x: 1, y: 2}
var b = {...a, y: 3 }
console.log(a); // { x: 1, y: 2 }
console.log(b); // { x: 1, y: 3 }
function updateVeryNestedField(state, action) {
// Create a temporary object to avoid use of computed keys
var updatedSecond = Object.assign({}, state.first.second);
updatedSecond[action.someId] = Object.assign({}, state.first.second[action.someId], {
fourth: action.someValue
});
return Object.assign({}, state, {
first : Object.assign({}, state.first, { second : updatedSecond })
});
}
var oldState = { first: { second: { 'anId': { fourth: 3 } } } };
var newState = updateVeryNestedField(oldState, { someId: 'anId', someValue: 5 });
console.log(oldState.first.second.anId.fourth); // 3
console.log(newState.first.second.anId.fourth); // 5
相当于
var c = { x: 1, y: 2 }
var d = Object.assign({}, a, { y: 3 });
console.log(c); // { x: 1, y: 2 }
console.log(d); // { x: 1, y: 3 }
重要的是a
和c
都没有变化b
和d
有一个新的y
值
对于嵌套对象,请重复此过程:
function updateVeryNestedField(state, action) {
return Object.assign({}, state, {
first : Object.assign({}, state.first, {
second : Object.assign({}, state.first.second, {
[action.someId] : Object.assign({},
state.first.second[action.someId],
{ fourth : action.someValue }
)
})
})
});
}
var oldState = { first: { second: { 'anId': { fourth: 3 } } } };
var newState = updateVeryNestedField(oldState, { someId: 'anId', someValue: 5 });
console.log(oldState.first.second.anId.fourth); // 3
console.log(newState.first.second.anId.fourth); // 5
但是,要获得ES2015的全面支持,您也无法。因此,您应该在return语句之前构建一些对象。例如:
var a = { x: 1, y: 2}
var b = {...a, y: 3 }
console.log(a); // { x: 1, y: 2 }
console.log(b); // { x: 1, y: 3 }
function updateVeryNestedField(state, action) {
// Create a temporary object to avoid use of computed keys
var updatedSecond = Object.assign({}, state.first.second);
updatedSecond[action.someId] = Object.assign({}, state.first.second[action.someId], {
fourth: action.someValue
});
return Object.assign({}, state, {
first : Object.assign({}, state.first, { second : updatedSecond })
});
}
var oldState = { first: { second: { 'anId': { fourth: 3 } } } };
var newState = updateVeryNestedField(oldState, { someId: 'anId', someValue: 5 });
console.log(oldState.first.second.anId.fourth); // 3
console.log(newState.first.second.anId.fourth); // 5
这在es5:[action.someId]:…
中是允许的吗?它在使用uglifier.js缩小时抛出了一个错误,其他人也遇到过这个问题。但是,它在绑定而不是缩小时通过。@不幸的是,skwy计算密钥是ES2015的一部分。我已经更新了我的示例,以演示如何通过引入临时对象来避免使用计算键。新示例使用索引向临时对象添加属性。再次感谢。。奇怪的是,它通过了捆绑,但没有通过缩小。我在用Browserify。也许在Browserify的绑定过程中内置了转换计算密钥?