如何在析构和循环中更新值

How to update a value in destructing and loop

我努力实现的目标:

我想更新 obj 中的值,它是数组元素的一部分。看下面的代码会给你更好的主意。

有一个问题,我通过引用更新对象的值,而不是制作 copy。这导致状态行为异常。

我尝试将其更改为复制,但我不确定。

例如

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: [],
};

我认为与其尝试提​​出一个使这项工作可行的解构语句,不如以更小的步骤更容易消化(并且可以说更具可读性):

  1. 浅拷贝objs;现在叫它 copy
  2. 重新创建 fields 数组及其中的每个项目
  3. 对于所需的数组项,更新其 value
  4. copy.fields设置为2
  5. 中创建的数组
// 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 或 sagas 了,所以我不确定 fields 是否需要一个全新的数组,或者是否只是 fields 中的更改对象需要是新的,但可以修改以上内容以满足任一需要。