我需要更新状态切片的切片,而不更新整个切片;只有子切片。我已经看到其他人联合使用减速器来实现这一目标,但我还没有想出如何在我的项目中做到这一点。 Redux.js.org将此作为另一种方式来实现:
function updateVeryNestedField(state, action) {
return {
....state,
first : {
...state.first,
second : {
...state.first.second,
[action.someId] : {
...state.first.second[action.someId],
fourth : action.someValue
}
}
}
}
}
不幸的是,我的项目是在javascript中。如何在没有扩展运算符的情况下使用vanilla javascript复制这个?我使用Object.assign
尝试了一些变体,但无法使其发挥作用。
答案 0 :(得分:1)
正如您所提到的,您可以使用Object.assign
代替传播:
{...state, x: 1}
应该给你与
相同的结果Object.assign({}, state, {x: 1})
请注意空对象作为Object.assign
的第一个参数。这样做是将值从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 }
相当于
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支持,您也无法use computed keys。因此,您必须在return语句之前构建一些对象。例如:
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