앞의 블로그 예제를 다시 사용하자. 먼저, 포스트에 새 댓글을 추가하는 예시를 보자.
기존 상태 액션의 컨텐츠에 병합 하는 것이다. 이 경우에 얕은 복사가 아닌 깊은 재귀병합을 해야한다. Lodash의 merge
함수는 이를 처리할 수 있다.
Copy import merge from "lodash/merge";
function commentsById(state = {}, action) {
switch(action.type) {
default : {
if(action.entities && action.entities.comments) {
return merge({}, state, action.entities.comments.byId);
}
return state;
}
}
}
이케하면 리듀서는 최소 작업량을 필요로한다. 하지만 action creator는 액션을 디스패치 하기 전에 적당한 형태로 구성하기 위해 2배의 작업을 필요로 한다.
슬라이스 리듀서가 중첩된 트리가 있다면 각 슬라이스 리듀서는 액션에 적절히 응답하는 법을 알고 있어야 한다. 일단 포스트 새 댓글을 추가하는 예시를 계속 사용한다고 하자
Copy // actions.js
function addComment(postId, commentText) {
const commentId = generateId("comment");
return {
type: 'ADD_COMMENT',
payload: {
postId,
commentId,
commentText
}
}
}
// reducers/post.js
// 해당 post 객체에 댓글 id 추가하기
function addComment(state, action) {
const {payload} = action;
const {postId, commentId} = payload;
const post = state[postId];
return {
...state,
[postId]: {
...post,
comments: post.comments.concat(commentId)
}
}
}
function postsById(state = {}, action) {
switch(action.type) {
case "ADD_COMMENT": return addComment(state, action);
default: return state;
}
}
function allPosts(state = [], action) {
}
const postsReducer = combineReducers({
byId: postsById,
allIds: allPosts
})
Copy // reducers/comment.js
function addCommentEntry(state, action) {
const {payload} = action;
const {commentId, commentText} = payload;
const comment = {id: commentId, text: commentText};
return {
...state,
[commentId]: comment
}
}
function commentsById(state = {}, action) {
switch(action.type) {
case "ADD_COMMENT": return addCommentEntry(state, action);
default: return state;
}
}
function addCommentId(state, action) {
const {payload} = action;
const {commentId} = payload;
// 새 댓글 ID를 전체 ID 리스트에 추가
return state.concat(commentId);
}
function allComments(state = [], action) {
switch(action.type) {
case "ADD_COMMENT" : return addCommentId(state, action);
default : return state;
}
}
const commentsReducer = combineReducers({
byId : commentsById,
allIds : allComments
});
이 예제는 슬라이스 리듀서와 케이스 리듀서를 어떻게 맞추고 있는지 보여주고 있다. 여기에서 위임에 유의하자. postsById
슬라이스 리듀서는 새로운 댓글 ID를 적절한 포스트에 삽입하는 작업을 addComment
에 위임한다. 반면 commentsById와 allComments 슬라이스 리듀서는 댓글 룩업테이블과 전체 댓글 ID를 적절히 업데이트하는 자신의 케이스 리듀서를 가지고 있다.