I am trying to dispatch an action that modifies the "matrix" array in the state,the array is getting modified,but the component is updated only if I hardcode the returned array inside the MUp() function.
The Reducer:
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;
};
The Action:
export const moveUp = () => {
return {
type: MOVE_UP,
};
};
And The Function Where I Dispatch The Action:
export const Moves = () => {
const dispatch = useDispatch();
document.addEventListener("keydown", function (e) {
if (e.key === "ArrowUp") dispatch(moveUp());
});
return null;
};
Your reducer appears to be mutating the existing array. let mat = state.matrix
just creates another reference to the same array in memory, and mat[i][j] =
also mutates the nested array.
A critical rule of immutable updates is that you must copy every level of nesting that you need to update. So, you'd need to make a copy of state.matrix
and state.matrix[i]
.
Note that you should really be usingour official Redux Toolkit package . Not only does it detect accidental mutations like this, it would actually let you write this same "mutating" logic, but RTK automatically turns those "mutations" into a safe and correct immutable update internally using Immer:
https://redux.js.org/tutorials/fundamentals/part-8-modern-redux#immutable-updates-with-immer
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.