-
카테고리
-
세부 분야
풀스택
-
해결 여부
미해결
댓글 수정 기능 추가 문제
21.08.27 10:08 작성 조회수 597
0
안녕하세요 제로초 선생님. 댓글 수정 기능을 추가하던 도중에 React의 성질과 관련하여 질문이 생겨 질문드립니다.
PostCard.js에서 CommentForm 컴포넌트와 CommentEditForm 컴포넌트 2개로 구성을 바꿨습니다. 그리고 post 데이터를 props로 넘겨주었습니다.
{commentFormOpened && (
<div>
<CommentForm post={post} />
<CommentEditForm post={post} />
</div>
)}
CommentForm.js는 아래와 같습니다
...
const CommentForm = ({ post }) => {
const dispatch = useDispatch();
...
useEffect(() => {
if (addCommentDone) {
setCommentText('');
}
}, [addCommentDone]);
const onSubmitComment = useCallback(() => {
console.log(id, post.id, commentText);
dispatch({
type: ADD_COMMENT_REQUEST,
data: { content: commentText, postId: post.id, userId: id },
});
}, [commentText, id]);
return (
<>
<Form onFinish={onSubmitComment}>
<Form.Item style={FormItem}>
<Input.TextArea
rows={4}
value={commentText}
onChange={onChangeCommentText}
/>
<Button
style={ButtonStyle}
type="primary"
htmlType="submit"
loading={addCommentLoading}
>
게시
</Button>
</Form.Item>
</Form>
</>
);
};
CommentForm.propTypes = {
post: PropTypes.object.isRequired,
};
export default CommentForm;
CommentEditForm.js는 아래와 같습니다
...
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(() => {
dispatch({
type: REVISE_COMMENT_REQUEST,
data: {
content: editText,
PostId: post.id,
UserId: id,
},
});
}, [editText, 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={[
<div style={{ fontSize: '13px', marginRight: '10px' }}>
{moment(item.createdAt).format('MM.DD HH:mm')}
</div>,
<span style={{ fontSize: '13px' }} onClick={onClickReviseComment}>
수정하기
</span>,
]}
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}
/>
)}
/>
)}
</div>
);
};
CommentEditForm.propTypes = {
post: PropTypes.object.isRequired,
};
export default CommentEditForm;
게시글 수정때와 유사하게 컴포넌트를 만들었는데, 이렇게 만들고 comment를 열려고 하면
이런 오류가 출력됩니다. post.Comments가 undefined라는 것인데, postCard.js은 index.js로부터 post를, CommentEditForm은 postCard.js로부터 post를 전달 받고 있어 index.js -> PostCard.js -> CommentEditForm 이렇게 2개 계층을 걸쳐 post를 전달받고 있기 때문에 이런 문제가 발생하는 것일까요?
답변을 작성해보세요.
0
조현영
지식공유자2021.08.27
말 그대로 post.Comments가 안 들어있는 겁니다.
post는 누가 보내주는 건지 생각해보시면 됩니다. post는 서버에서 옵니다. 따라서 post.Comments도 서버에서 오겠죠. 서버에서 post.Comments를 안 넣어준 겁니다. 서버쪽 라우터에서 post에 comments가 include되지 않은 겁니다.
긴장한 곰
질문자2021.08.27
감사합니다! 근데 추가로 궁금한 것이 생겼는데, 만약에 댓글을 지우거나 수정하려고 하면 댓글의 id가 필수적으로 필요할 것 같은데 이를 찾을 수 있는 방법을 잘 모르겠습니다.
예를 들어, reducer에서
case REMOVE_COMMENT_SUCCESS: {
// 지우고자 하는 댓글이 달린 게시글 찾기
const post = draft.mainPosts.find((v) => v.id === action.data.PostId);
// 그 게시글의 댓글 찾기 (객체)
const comment = post.find((v) => v.id === action.data.UserId);
...
}
여기까지 하면 게시글을 찾고, 그 게시글 안에서 특정 사용자가 작성한 댓글까지는 찾을 수 있을 것 같습니다. 그런데 그 특정 사용자가 댓글을 하나가 아니라 여러개를 달았을 수도 있는데 이를 구분해내는 방법을 생각해내는 데에서 막혔습니다.
const onRemoveComment = useCallback(() => {
if (!id) {
return alert('로그인이 필요합니다');
}
return dispatch({
type: REMOVE_COMMENT_REQUEST,
data: {
PostId: post.id,
UserId: id,
},
});
}, [id]);
현재는 프론트에서 PostId와 UserId만 받아온 뒤에 reducer에서 PostId와 UserId만을 이용해 특정 댓글을 찾아내려고 하고 있는데, 프론트에서 지우려고하는 댓글의 id까지 받아올 수 있는 방법이 있을까요?
답변 1