我想达到的目标:
我想更新一个obj中的值,它是数组元素的一部分。看下面的代码会给你更好的想法。
有一个问题,我更新对象的值,通过引用,而不是使复制。这会导致状态行为异常。
我试着把它改成复制,但我不确定。
。
const returnObj = {
...objs,
fields: [{name, value}, {name, value}, {name, value_update_this_only}, ...],
};
// This is the current code
export function* onChange(action) {
// get partial state from redux state
const list = yield select((state) => state.list);
let objs = list[action.index];
// * e.g. objs.fields === [{name, value}, {name, value}, ...]
// * basically following, find the correct field and update its value
// * following has problem, beause we change the value of a reference,
// * instead we should make a new copy, so redux can react
objs.fields.map((field) => {
if (field.name === action.fieldName) {
field["value"] = action.fieldValue;
}
return field;
});
// fire to redux reducer
yield put({
type: "UPDATE",
prop: obj,
docIndex: action.index,
});
}
// the problem: I don't know how to do it in destructing manner.
const returnObj = {
...objs,
fields: [],
};
我认为与其尝试用单个解构语句来完成这项工作,不如用更小的步骤来更容易理解(并且可以说更具可读性):
- 对
objs
进行浅拷贝;现在叫它copy
- 创建
fields
数组和其中的每个项目 - 对于所需的数组项,更新其
value
- 设置
copy.fields
为2 中创建的数组
// Step 1: Shallow copy
let copy = { ...objs }
// Step 2: Recreate fields and every item
let fields = copy.fields.map((field) => ({
...field
}))
// Step 3: Update value of desired item
fields.forEach((field) => {
if (field.name === action.fieldName)
field.value = action.fieldValue
})
// Step 4: Reassign fields to the copy
copy.fields = fields
重构后,步骤2-4可以合并成一个步骤,而不会牺牲太多的可读性:
let copy = { ...objs }
copy.fields = copy.fields.map((field) => ({
...field,
value: field.name === action.fieldName ? action.fieldValue : field.value,
}))
自从我使用redux或saga以来已经很长时间了,所以我不确定fields
是否需要成为一个全新的数组,或者如果只是fields
中的更改对象需要是新的,但是上面可以修改以适应任何需要。