我正在尝试调度一个修改状态中“矩阵”数组的操作,该数组正在被修改,但只有当我在 MUp() 函数中对返回的数组进行硬编码时才会更新组件。
减速器:
export const initialState = {
board: {
matrix: [
[4, 2, 0, 0],
[4, 2, 4, 0],
[4, 0, 16, 2],
[4, 2, 32, 0],
],
},
};
export const board = (state = initialState.board, action) => {
if (action.type == MOVE_UP) {
return {
...state,
matrix: MUp(state),
};
}
return state;
};
const MUp = (state) => {
let mat = state.matrix;
const size = state.gridSize;
var ok;
for (var j = 0; j < size; j++) {
ok = 1;
while (ok) {
ok = 0;
for (var i = size - 2; i >= 0; i--) {
if (mat[i][j] != 0) {
if (mat[i + 1][j] == mat[i][j]) {
mat[i][j] = 0;
mat[i + 1][j] = 2 * mat[i + 1][j];
ok = 1;
} else {
if (mat[i + 1][j] == 0) {
mat[i + 1][j] = mat[i][j];
mat[i][j] = 0;
ok = 1;
}
}
}
}
}
}
console.log("up");
return mat;
};
行动:
export const moveUp = () => {
return {
type: MOVE_UP,
};
};
以及我调度动作的函数:
export const Moves = () => {
const dispatch = useDispatch();
document.addEventListener("keydown", function (e) {
if (e.key === "ArrowUp") dispatch(moveUp());
});
return null;
};
答案 0 :(得分:1)
您的减速器似乎正在改变现有数组。 let mat = state.matrix
只是在内存中创建另一个对 same 数组的引用,而 mat[i][j] =
也会改变嵌套数组。
不可变更新的一个关键规则是您必须复制您需要更新的每个嵌套级别。因此,您需要复制 state.matrix
和 state.matrix[i]
。
请注意,您确实应该使用 our official Redux Toolkit package。它不仅可以检测到这样的意外突变,实际上还可以让您编写相同的“突变”逻辑,而且 RTK 会在内部使用 Immer 自动将这些“突变”转换为安全且正确的不可变更新:
https://redux.js.org/tutorials/fundamentals/part-8-modern-redux#immutable-updates-with-immer