尽管使用Object.assign和Spread语法,对象仍在Redux中发生突变

问题描述 投票:0回答:1

我在Redux Saga中具有生成器函数,该函数获取ID,获取状态并调度一个具有该状态的操作,而其中没有带有匹配ID的对象键。还原器中应该替换且未突变的对象看起来像这样:

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

当此函数使用注释掉的delete运算符运行时,它将在redux和所有Redux记录器中(在更改前和更改后)更改整个状态,并且我的选择器将返回以前的备注版本,因为未检测到更改。我通过用lodash Omit创建一个新对象解决了这个问题,但是有没有更快的方法或<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 }));
}
javascript reactjs typescript redux redux-saga
1个回答
0
投票

Object.assign对对象进行浅表复制,这意味着顶层的对象有所不同,但嵌套的对象仍引用先前的对象。在这里,您要更改嵌套对象的引用,该嵌套对象与redux存储中的对象具有相同的引用,从而使redux状态发生变化。您也可以尝试复制嵌套对象,如下所示:

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 }));
}
© www.soinside.com 2019 - 2024. All rights reserved.