데이터베이스 통신하는 리뷰창 구현하기!

Hyodduru ·2022년 4월 3일
0

Projects

목록 보기
3/7

저번주부터 한창 웹사이트 만들기 프로젝트 진행중이다,,, (프론트엔드는 리액트 기반)

이번에 처음으로 제대로 백엔드와 통신하는 법을 배우고 연습하고 익숙해지고 있다. 따로 임의로 가상의 데이터(mock data)를 활용해 ui를 구현하다가 오늘 웹사이트 내에 리뷰 컴포넌트를 만들어서 작성한 리뷰 데이터베이스에 전송하고, 전송이 성공하면 바로 데이터를 다시 전송받아서 리뷰 컴포넌트 내에 렌더링해주는 작업을 했다(!!!)

결론부터 말하면 너무 신기했다.

가상의 데이터 가지고 놀다가 처음으로 통신이 될 때의 그 짜릿함(?)

아무튼 그 과정에 대해 조금 공유해보고자 한다...(!)

리뷰창 레이아웃 및 기능 구현 순서

  1. 리뷰 컴포넌트 및 리뷰 작성 모달창 레이아웃
  2. 리뷰 모달창 내의 textarea에 글 작성 후 database로 전송 한다.
  3. 전송 후 리뷰 컴포넌트 내에 추가된 댓글을 화면으로 렌더링 한다.
  4. 리뷰 삭제 버튼 클릭시 데이터 베이스로부터 삭제 요청한다.

🚀 1. 리뷰 컴포넌트 및 리뷰 작성 모달창 레이아웃

리뷰 컴포넌트는 제품의 상세페이지 안에 포함되어있는 컴포넌트이다.
리뷰 컴포넌트는 상세페이지로부터 해당 제품에 대한 정보를 prop으로 전달을 받고, 그 해당 제품에 관한 리뷰들을 볼 수 있는 공간!

그리고 그 리뷰 컴포넌트 내에 "add to review"라는 버튼을 만들어서 해당 버튼을 클릭시 모달창을 띄워주는 로직을 구현했다.

(모달창 만드는 방법은 아-주! 간단하다! 그것도 조만간 포스팅 하겠음(!!!))

그리고 띄워진 모달창은 리뷰를 새롭게 작성할 수 있는 공간이다.

🚀 2. 리뷰 모달창 내의 textarea에 글 작성 후 database로 전송

리뷰 작성 모달창 내에서 textarea에 글 작성 후 create a review 버튼을 클릭할 시 fetch함수를 이용하여 데이터베이스에 해당 댓글 내용을 전송하는 로직이다.
댓글의 내용은 onChange event와 state를 활용하여 저장한다.

코드는 아래와 같다.

const submitReview = () => {
    fetch('API 주소', {
      method: 'post',
      headers: {
        Authorization:
          'token 적어주기',
      },
      body: JSON.stringify({
        content: content,
      }),
    })
      .then(res => {
        if (res.ok) {
          alert('리뷰 등록이 완료되었습니다.');
        } else {
             console.log('error');
        }
        return res.json();
      })      
      .catch(error => console.error(error.message));
      
      
      return
      // 관련없는 코드 생략 
      
      <button
            className="postBtn"
            onClick={() => {submitReview()}>
            Post Review
          </button>

🚀 3. 전송 후 리뷰 컴포넌트 내에 추가된 댓글을 화면으로 렌더링 한다.

이때 나는 post를 하고나서 또 따로 새롭게 get을 해줘야하나 했는데 promise내에서 데이터를 전송하고난후 거기서 then을 적고 다시 그 api 주소를 fetch할 수도 있다고 한다(!)

feat ) 오늘 완쾌해서 돌아오신 재도님께서,, 알려주셨다(!!!)

그래서 다시 get해주는 부분까지 적어보면,

const submitReview = () => {
    fetch('API 주소', {
      method: 'post',
      headers: {
        Authorization:
          '토큰 적어주기',
      },
      body: JSON.stringify({
        content: content,
      }),
    })
      .then(res => {
        if (res.ok) {
          alert('리뷰 등록이 완료되었습니다.');
        } else {
          console.log('error');
        }
        return res.json();
      })
      .then(data => {
        fetch('http://10.58.2.64:8000/products/1')
          .then(res => res.json())
          .then(data => setReviewList(data.result.reviews));
      })
      .catch(error => console.error(error.message));
  };

이렇게 된다.

새로 작성한 댓글을 전송해주고나서 바로 업데이트된 데이터를 전달받는 로직이다.

데이터를 전달받으면 바로 리뷰 컴포넌트(부모 컴포넌트)로 부터 전달받은 setReviewList(리뷰리스트 값 설정하는 곳)에 reviews를 저장을 해주고, 리뷰 컴포넌트에서 해당 데이터를 렌더링해준다!

  <ul className="reviewList">
        {reviewList.length > 0 &&
          reviewList.map((li, i) => {
            const { review_id, user, content, created_at } = li;
            const [day, month, date, year] = Date(created_at)
              .split(' ')
              .slice(0, 4);
            return (
              <li key={i} className="reviewCard">
                <button
                  id={review_id}
                >
                  <i className="fas fa-times" />
                </button>
                <div className="row">
                  <h3 className="userId">{user}</h3>
                  <span className="createdTime">
                    {year}/ {month} / {date} / {day}
                  </span>
                </div>
                <p className="contents">{content}</p>
              </li>
            );
          })}
      </ul>

원하는 위치에 해당하는 데이터 적어주는 방식!

신기했던 건 백엔드에서 내가 리뷰를 작성한 시간까지 저장되도록 로직을 구현해주셔서 (감사합니다 원빈님,,ㅎ) 시간 또한 렌더링할 수 있었음!!!!

시간은 'December 17, 1995 03:24:00' 이런 형태로 전송이 되어서

const [day, month, date, year] = Date(created_at).split(' ').slice(0, 4); 이렇게 날짜, 월, 일, 년 까지 쪼개서 원하는 위치로 변경해주었다!

🚀 4. 리뷰 삭제 버튼 클릭시 데이터 베이스로부터 삭제 요청

header에 저장된 토큰 값을 보내줌과 동시에 내가 삭제하고자 하는 리뷰의 아이디를 넘겨준다!그리고나서 바로 새로운 데이트 state에 update 해주기!!
오늘 해봤는데 문제없이 잘 작동했다-!

 const deleteReview = e => {
    fetch(`${API.products}/1?review-id=${e.target.id}`, {
      method: 'DELETE',
      headers: {
        Authorization:
          '토큰!',
      },
    })
      .then(res => res.json();
      )
      .then(data => {
        if (data.message === 'deleted') {
          fetch(`${API.products}/1`)
            .then(res => res.json())
            .then(data => {
              setReviewList(data.result.reviews);
            });
        }
      });
  };

🍯 마무리

넘 재밌다,,, 레이아웃 계속 하다가 통신해보니 생동감 있구 재밌네,,, ^^ 근데 해보고 싶은 건 리뷰에서 삭제 버튼을 해당 로그인을 한 사람 거에만 보여주게 하고 싶은데,, 그건 어떻게 해야할지 모르겠다. 그리고 삭제도 내가 작성한 글만 하게 하고 싶은데,, 미래의 나야 해결해줘!!!!!!

profile
꾸준히 성장하기🦋 https://hyodduru.tistory.com/ 로 블로그 옮겼습니다

0개의 댓글