尽管 Object.assign 和 Spread 语法,对象在 Redux 中发生变异
Object mutates in Redux despite Object.assign and Spread syntax
我在 Redux Saga 中有一个生成器函数,它获取一个 ID,获取状态并分派一个带有状态的动作,其中没有带有匹配 ID 的对象键。 reducer 中的对象它应该被替换而不是变异看起来像这样:
{
[CURRENT YEAR]: {
[DAY OF YEAR]: {
[ID THAT SHOULD BE DELETED]: {}
},
},
};
当此函数 运行 使用注释掉的删除运算符时,它将改变 redux 和所有 Redux 记录器(更改前和更改后)中的整个状态,而我的选择器将 return 之前的记忆版本,因为未检测到任何更改。我通过使用 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 }));
}
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 }));
}
我在 Redux Saga 中有一个生成器函数,它获取一个 ID,获取状态并分派一个带有状态的动作,其中没有带有匹配 ID 的对象键。 reducer 中的对象它应该被替换而不是变异看起来像这样:
{
[CURRENT YEAR]: {
[DAY OF YEAR]: {
[ID THAT SHOULD BE DELETED]: {}
},
},
};
当此函数 运行 使用注释掉的删除运算符时,它将改变 redux 和所有 Redux 记录器(更改前和更改后)中的整个状态,而我的选择器将 return 之前的记忆版本,因为未检测到任何更改。我通过使用 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 }));
}
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 }));
}