[React] 게시물 댓글달기

M_yeon·2022년 9월 11일
0

React

목록 보기
6/23

만들어놓은 게시물 상세페이지에서 댓글 UI를 구현 후 댓글 등록 및 수정 삭제를 진행 해보려고 합니다.

1. state 만들기

작성자, 비밀번호, 댓글작성란 부분에 대해서 state를 만들어 주면 됩니다.
저는 state들이 여러줄 있는게 불편해서 객체로 만들었습니다

  const [comment,setComment] = useState({
    writer:"",
    password:"",
    contents:""
  })

2. onchange 이벤트

이제 state에서 작성한 setComment 안에 초기값이 빈값이니까
onchange 이벤트 안에서 event.target.value 로 설정하여 이벤트를 통해 클릭한 타겟의 value값을 setComment에 집어넣겠다라는 구문입니다.

  const onChangeWriter = (event) => {
    setComment({...comment, writer:event.target.value})
  }
  const onChangePassword = (event) => {
    setComment({...comment, password:event.target.value})
  }
  const onchangeContents = (event) => {
    setComment({...comment, contents:event.target.value})
  }
---

## 3.graphQL 쿼리문 작성
우선 graphQL에서 gql를 불러오도록 하겠습니다
```javascript
export const CREATE_BOARD_COMMENT = gql`
  mutation createBoardComment($createBoardCommentInput: CreateBoardCommentInput!,
    $boardId: ID!) {
    createBoardComment(
      createBoardCommentInput: $createBoardCommentInput
      boardId: $boardId
    ) {
      _id
      writer
      contents
      rating
      createdAt
    }
  }
`;

사용할 페이지에 최상단에 CREATE_BOARD_COMMENT를 불러와서 이 쿼리문을 사용하겠다고 선언을 해준 뒤

import {CREATE_BOARD_COMMENT, FETCH_BOARD} from '../../../commons/BoardWrite.queryes'

Mutatin도 같이 작성 해줍니다


 const [createBoardComment] = useMutation(CREATE_BOARD_COMMENT)

4.onClick 함수 만들기

등록하기 버튼을 눌렀을때 실행되는 로직을 작성하고 return 부분에 onchange와 같이 props를 해주기 위해 함수명을 적어줍니다.

  const onClickComment = async () => {
    try{
      const result = await createBoardComment({
        variables:{
          createBoardCommentInput:{
            writer:comment.writer,
            password:comment.password,
            contents:comment.contents,
            rating: 5,
          },
          boardId:router.query.boardId,
        },
      })
      console.log(result)
      console.log(result.data.createBoardComment.boardId)
      alert("댓글 등록이 완료되었습니다.")
    }catch(error){
      alert(error.message)
   } 
  }
  return(
    <>
      <BoardDetailUI data={data}
      onClickMoveToBoard={onClickMoveToBoard}
      goEdit={goEdit}
      updateData={props.data}
      onClickComment={onClickComment}
      onChangeWriter={onChangeWriter}
      onChangePassword={onChangePassword}
      onchangeContents={onchangeContents}
      />
    </>
  )

여기까지 하게되면 댓글등록이 완료되었습니다가 출력됩니다.
이제 fetch와 refetch를 진행해볼게요~!!~

자! FETCH 도 똑같이 graphQL에 가서 작성해봅시다.

1. graphQL 쿼리문 작성

아래처럼 graphQL 사이트에 있는 그대로 작성을 해주면 됩니다.

export const FETCH_BOARD_COMMENTS = gql`
  query fetchBoardComments($boardId:ID!){
    fetchBoardComments(boardId: $boardId){
      _id
      writer
      contents
      rating
      createdAt
      updatedAt
    }
  }
`

2.refetchQueres 작성

onClick 함수안에 refetchQueres를 넣어주기 전에 useQuery도 함께 작성해줍니다!

  const {data : commentData} = useQuery(FETCH_BOARD_COMMENTS,{
    variables:{boardId:router.query.boardId}
  })
  const onClickComment = async () => {
    try{
      const result = await createBoardComment({
        variables:{
          createBoardCommentInput:{
            writer:comment.writer,
            password:comment.password,
            contents:comment.contents,
            rating: 5,
          },
          boardId:router.query.boardId,
        },
        refetchQueries:[{
          query: FETCH_BOARD_COMMENTS,
          variables:{boardId:router.query.boardId}
        },]
      })
      console.log(result)
      console.log(result.data.createBoardComment.boardId)
      alert("댓글 등록이 완료되었습니다.")
    }catch(error){
      alert(error.message)
   } 
  }

그 다음 재 조회한 결과 fetch 데이터를 내려보내주기 위해 data를 return에 작성해줍니다.

  return(
    <>
      <BoardDetailUI
      	commentData={commentData}
      />
    </>
  )

3.Map 을 돌린다.

댓글이 하나씩 fetch데이터를 가지면서 늘어나야 하니까 하나의 component로 만들어서 Map을 돌려줍니다.

import * as S from '../../../../../../styles/fetchboard'

export default function BoardCommentsMap({commentData}){
  console.log(commentData)

  return(
    <>
    {commentData?.fetchBoardComments.map((comment, _id) => (
      <S.Users key={comment._id}>
        <S.Userbx>
          <S.Leftbx>
            <S.User></S.User>
            <S.Rebx>
              <S.Reviewname>{comment.writer}
                  <S.Icon src="/star.png" alt="별점아이콘"></S.Icon>
                  <S.Icon src="/star.png" alt="별점아이콘"></S.Icon>
                  <S.Icon src="/star.png" alt="별점아이콘"></S.Icon>
                  <S.Icon src="/star.png" alt="별점아이콘"></S.Icon>
                  <S.Icon src="/star.png" alt="별점아이콘"></S.Icon>
              </S.Reviewname>
              <S.Reviewdate>{comment.contents}</S.Reviewdate>
            </S.Rebx>
        </S.Leftbx>
          <S.Right>
            <S.Icon src="/rewrite.png" alt="글쓰기아이콘"></S.Icon>
            <S.Icon src="/delete.png" alt="지우기아이콘"></S.Icon>
          </S.Right>
        </S.Userbx>
        <S.Today>{comment.createdAt}</S.Today>
      </S.Users>
      ))}
    </>
  )

}

여기까지의 내 오류상황은

쿼리에서 타입을 변수명으로 지정 안해줘서 오류 남.
data는 usequery를 사용하면 객체로 변환되기 때문에 data가 사용중일 때에는 data: commentData 이렇게 해야한다. (근데 안해서 오류남)

0개의 댓글