繁体   English   中英

尽管 Object.assign 和 Spread 语法,Object 在 Redux 中发生变异

[英]Object mutates in Redux despite Object.assign and Spread syntax

I have a generator function in a Redux Saga that gets an ID, gets the state and dispatches a an action with the state without the object key with the matching id in it. 减速器中的 object 应该替换为未突变,如下所示:

{
    [CURRENT YEAR]: {
      [DAY OF YEAR]: {
        [ID THAT SHOULD BE DELETED]: {}
      },
    },
};

When this function ran using the commented out delete operator it would mutate the entire state in redux and in ALL Redux loggers (prev and after change) and my selectors would return the previous memoized version because no change was detected. 我通过使用 lodash Omit 创建一个新的 object 解决了这个问题,但是有没有更快或小于 21kb 的解决方案呢?

function* removeExerciseAsync(action: any) {
  const { currentDate, currentYear }: DateState = yield select((state: AppState) => state.date);
  const years = yield select(selectYears);

  const dayOfYear = currentDate.dayOfYear();


  const newYearState: DaySummaryTypes = Object.assign({}, years[currentYear]);

  const exerciseId = action.payload;

  if (!newYearState[dayOfYear][exerciseId]) return;

  // delete newYearState[dayOfYear][exerciseId];

  const newState = omit(newYearState, `${dayOfYear}.${exerciseId}`);

  yield put(updateYearExercises({ [currentYear]: newState }));
}

Object.assign做了 object 的浅拷贝,这意味着顶层的 object 不同,但嵌套对象仍然引用以前的对象。 Here you're making change to the nested object that has the same reference as the object sitting in your redux store, hence mutating the redux state. 您也可以尝试复制嵌套的 object ,如下所示:

function* removeExerciseAsync(action: any) {
  const { currentDate, currentYear }: DateState = yield select((state: AppState) => state.date);
  const years = yield select(selectYears);

  const dayOfYear = currentDate.dayOfYear();


  const newYearState: DaySummaryTypes = {
    ...years[currentYear],
    [dayOfYear]: {
      ...years[currentYear][dayOfYear]
    }
  };

  const exerciseId = action.payload;

  if (!newYearState[dayOfYear][exerciseId]) return;

  delete newYearState[dayOfYear][exerciseId];

  // const newState = omit(newYearState, `${dayOfYear}.${exerciseId}`);

  yield put(updateYearExercises({ [currentYear]: newState }));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM