제로초 선생님 강의를 듣고 나서 댓글 삭제 기능과 수정 기능 및 좋아요 갯수를 세는 기능 등을 만들어보고 있는데 아직 실력이 부족해서 그런지 상당히 헷갈리네요. 나머지는 추가로 해보려고 하고 댓글 삭제 기능만 먼저 질문드리겠습니다..!
CommentEditForm.js
...
import CommentRemoveBtn from './CommentRemoveBtn';
const { TextArea } = Input;
const CommentEditForm = ({ post }) => {
const dispatch = useDispatch();
const id = useSelector((state) => state.user.me?.id);
const [editText, setEditText] = useState('');
const [commentEditMode, setCommentEditMode] = useState(false);
const onReviseCommentText = useCallback((e) => {
setEditText(e.target.value);
});
const { reviseCommentLoading } = useSelector((state) => state.post);
const onReviseComment = useCallback((CommentId) => () => {
dispatch({
type: REVISE_COMMENT_REQUEST,
data: {
content: editText,
PostId: post.id,
UserId: id,
CommentId,
},
});
}, [editText, id]);
const onRemoveComment = useCallback((CommentId) => () => {
if (!id) {
return alert('로그인이 필요합니다');
}
return dispatch({
type: REMOVE_COMMENT_REQUEST,
data: {
CommentId,
PostId: post.id,
},
});
}, [post.id]);
const onClickReviseComment = useCallback(() => {
setCommentEditMode(true);
});
const onCancelReviseComment = useCallback(() => {
setCommentEditMode(false);
}, []);
return (
<div>
{commentEditMode
? (
<>
<TextArea value={editText} onChange={onReviseCommentText} />
<Button.Group>
<Button loading={reviseCommentLoading} onClick={onReviseComment}>수정</Button>
<Button type="danger" onClick={onCancelReviseComment}>취소</Button>
</Button.Group>
</>
)
: (
<List
header={`${post.Comments.length}개의 댓글`}
itemLayout="horizontal"
dataSource={post.Comments || []}
renderItem={(item) => (
<li>
<Comment
actions={id && item.User.id === id
? [
<div style={{ fontSize: '13px', marginRight: '10px' }}>
{moment(item.createdAt).format('MM.DD HH:mm')}
</div>,
<span style={{ fontSize: '13px' }} onClick={onClickReviseComment}>
수정하기
</span>,
<CommentRemoveBtn onRemoveComment={onRemoveComment(item.id)} />,
]
: [
<div style={{ fontSize: '13px', marginRight: '10px' }}>
{moment(item.createdAt).format('MM.DD HH:mm')}
</div>,
]}
author={item.User.nickname}
avatar={(
<Link href={`/user/${item.User.id}`} prefetch={false}>
<a><Avatar>{item.User.nickname[0]}</Avatar></a>
</Link>
)}
content={item.content}
/>
</li>
)}
/>
)}
</div>
);
};
CommentEditForm.propTypes = {
post: PropTypes.object.isRequired,
};
export default CommentEditForm;
댓글 삭제 기능을 구현하기 위해서 onRemoveComment 이벤트를 만들고, '삭제하기' 버튼을 누르면 REMOVE_COMMENT_REQUEST가 실행되면서 PostId와 CommentId를 넘겨주었습니다.
reducers/post.js
case REMOVE_COMMENT_REQUEST:
draft.removeCommentLoading = true;
draft.removeCommentDone = false;
draft.removeCommentError = null;
break;
case REMOVE_COMMENT_SUCCESS: {
const post = draft.mainPosts.find((v) => v.id === action.data.PostId);
draft.removeCommentLoading = false;
draft.removeCommentDone = true;
draft.mainPosts = post.Comments.filter((v) => v.id !== action.data.CommentId);
break;
}
case REMOVE_COMMENT_FAILURE:
draft.removeCommentLoading = false;
draft.removeCommentError = action.error;
break;
routes/post.js
router.delete('/:postId/comment', isLoggedIn, async (req, res, next) => { // DELETE /post/1/comment
try {
const comment = await Comment.findOne({ where: { PostId: req.params.postId, UserId: req.user.id } });
await Comment.destroy({
where: { id: comment.id },
include: [{
model: User,
attributes: ['id', 'nickname'],
}],
});
res.status(200).json({ id: comment.id, PostId: parseInt(req.params.postId, 10), UserId: req.user.id });
} catch (error) {
console.error(error);
next(error);
}
});
리듀서와 라우터는 위와 같이 만들었는데, db에서는 정상적으로 댓글이 지워지지만 화면에서는 반영이 안됩니다.
![](https://cdn.inflearn.com/public/files/posts/7039ebd5-4e57-46e4-a8b5-fe3dcc477538/blob)
확실히 리듀서 코드를 잘못 짜줬기 때문에 위와 같이 댓글뿐만 아니라 다른 것까지 다 지워버리는 현상이 발생하는 것 같은데, mainPosts라는 배열 안에 객체가 있고, 그 안에 Comments가 또 배열 객체를 가지고 있다보니 이를 지우는 것이 매우 헷갈리는 것 같습니다.
case REMOVE_COMMENT_REQUEST:
draft.removeCommentLoading = true;
draft.removeCommentDone = false;
draft.removeCommentError = null;
break;
case REMOVE_COMMENT_SUCCESS: {
const post = draft.mainPosts.find((v) => v.id === action.data.PostId);
draft.removeCommentLoading = false;
draft.removeCommentDone = true;
draft.mainPosts = post.Comments.filter((v) => v.id !== action.data.CommentId);
break;
}
case REMOVE_COMMENT_FAILURE:
draft.removeCommentLoading = false;
draft.removeCommentError = action.error;
break;
이 리듀서를 어떻게 수정하는 것이 좋을까요..?
답변 1