리덕스는 이전 상태와 액션을 기반으로 상태를 업데이트하는 순수 함수로, state를 직접 변경해서는 안된다.
React-toolkit
의 createSlice
를 사용하면 immer가 적용되기 때문에, 그냥 할당해도 순수성을 유지하면서 업데이트가 되기 때문에, 일일히 아래처럼 작성해줄 필요는 없다.
그렇지만 Immer
를 사용하지 않고 순수하게 업데이트하는 방식도 작성해 보았다.
interface NestedArrayData {
arr: ("RED" | "YELLOW" | null)[][];
}
interface ActionsData {
payload: {
lineNumber: number;
location: number;
currentUser: "RED" | "YELLOW";
};
}
export default function nestedArrayUpdate(
{ arr }: NestedArrayData,
actions: ActionsData
) {
return arr.map((line, index) => {
if (index !== actions.payload.lineNumber) {
return line;
}
return line.map((marker, idx) => {
if (idx !== actions.payload.location) {
return marker;
}
return actions.payload.currentUser;
});
});
}
const initialArray = [
[null, null, null, null, null, null],
[null, null, null, null, null, null],
[null, null, null, null, null, null],
[null, null, null, null, null, null],
[null, null, null, null, null, null],
[null, null, null, null, null, null],
[null, null, null, null, null, null],
];
const test1 = nestedArrayUpdate(
{
arr: initialArray,
},
{
payload: {
currentUser: "RED",
lineNumber: 5,
location: 5,
},
}
);
console.log("바뀐 객체:", test1, "기존 객체:", initialArray);
map으로 배열을 순회하면서 바꾸고 싶은 위치를 제외하고 모두 그대로 return하고, 바꾸어야 할 부분만 따로 처리해 준다.