🤍 전 강의 25% 할인 중 🤍

2024년 상반기를 돌아보고 하반기에도 함께 성장해요!
인프런이 준비한 25% 할인 받으러 가기 >>

  • 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    미해결

댓글 수정 기능 추가 문제

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(idpost.idcommentText);
    dispatch({
      type: ADD_COMMENT_REQUEST,
      data: { content: commentTextpostId: post.iduserId: id },
    });
  }, [commentTextid]);
  
  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 [editTextsetEditText] = useState('');
    const [commentEditModesetCommentEditMode] = 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,
                },
            });
        }, [editTextid]);

    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를 전달받고 있기 때문에 이런 문제가 발생하는 것일까요?

답변 1

답변을 작성해보세요.

0

말 그대로 post.Comments가 안 들어있는 겁니다.

post는 누가 보내주는 건지 생각해보시면 됩니다. post는 서버에서 옵니다. 따라서 post.Comments도 서버에서 오겠죠. 서버에서 post.Comments를 안 넣어준 겁니다. 서버쪽 라우터에서 post에 comments가 include되지 않은 겁니다.

감사합니다! 근데 추가로 궁금한 것이 생겼는데, 만약에 댓글을 지우거나 수정하려고 하면 댓글의 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까지 받아올 수 있는 방법이 있을까요? 

댓글 아이디를 action의 data로 넘겨주시면 됩니다.

채널톡 아이콘