React: 댓글 기능 구현

XCC629·2022년 3월 6일
0

댓글 기능을 구현하기 위해 알아야할 지식들

1. 이벤트

onKey... 이벤트들의 실행 시점

  1. onKeyPress()
    • 키가 눌리기 전까지만 실행된다.
      - 예를 들어 wow 라고 댓글을 달면 wo 까지만 나온다.
    • enter 키를 인식하지 않는다.
  2. onKeyDown()
    • 키가 눌리기 전까지만 실행된다.
      - 예를 들어 wow 라고 댓글을 달면 wo 까지만 나온다.
  3. onKeyup()
    • 키가 눌리고 나서 실행된다.
      -wow 라고 입력하면 wow가 다 나온다.

왜 이에 대한 지식이 필요한가?

  1. enter가 눌렸을 때 새로고침 되지 않도록 해야함
  2. input값을 끝까지 받아야 함

그렇다. 댓글 입력창에 2개의 이벤트를 분리해야한다는 말이다!!

2. 배열 메서드

array.prototype.map(()=>{})

map 메서드는 원래의 배열에 있는 요소 하나하나를 콜백함수에 맞게 처리하고 그 값을 return 해준다.

왜 알아야 하는가?

댓글 내용을 컴포넌트에 넣어서 return해줘야하기 때문이다!

구현하기

다른 좋은 방법이 있는 지는 모르겠지만, 나는 댓글 각각을 객체로 만들어 댓글을 합친 array를 만들고, 그 array를 화면에 나타나도록 하겠다.

useState

그러기 위해서는 댓글을 계속 받는 변수, 댓글을 모은 배열. 즉 2개의 state가 필요하다.

 const [review, setReview] = useState('우주최강맛임 대박ㅋㅋ');
  const [reviewArray, setReviewArray] = useState([
    { id: `초코덕후`, review: review },
  ]);

초기값으로 아무 말이나 써두었다.

event

그 다음으로, 이벤트에 대해서 생각해본다.

				<input
                  className="review-input"
                  type="text"
                  placeholder="리뷰를 입력해주세요."
                  onKeyPress={event => {
                    handleTotalEnter(event);
                  }}
                  onKeyUp={event => {
                    handleReviewInput(event);
                  }}
  1. onKeyPress 이벤트는 enter가 눌려도 새로고침을 안되게 할 것이며, enter가 눌린 이후에 댓글에 들어온 내용을 array에 넣어주는 함수를 받을 것이다. (handleTotalEnter의 역할)

  2. onKeyUp 이벤트는 댓글 내용을 받아서 review를 갱신해줄 것이다. 왜 onKeyUp을 썻는가는 위에서 설명했듯이, 이 이벤트가 댓글 내용을 끝까지 인식해주기 때문이다! (handleReviewInput의 역할)

callback functions

handleReviewInput()

const handleReviewInput = event => {
    setReview(event.target.value);
  };

이벤트의 타겟(input)의 값을 review에 계속 갱신해준다.

handleTotalEnter()

  const handleTotalEnter = event => {
    if (event.key === 'Enter') {
      event.preventDefault();
      const repoArray = [...reviewArray];
      if (event.target.value !== '')
        repoArray.push({ id: '익명', review: review });
      setReviewArray(repoArray);
      event.target.value = '';
    }
  };

논리

  1. 이벤트에서 눌린 키가 enter이면 일단 새로고침을 막는다.
  2. repoArray라는 새로운 배열에 지금까지의 배열을 저장한다.
  3. input에 들어 온 게 빈 값이 아닌지 확인한다.
    • 아무 내용없는 댓글을 받지 않아야하니까!
  4. 빈 값이 아니라면, id는 익명으로, 내용은 review에 들어온 값을 가진 객체를 repoArray에 넣는다.
  5. repoArray의 값으로 reviewArray를 갱신한다.
  6. 이미 들어간 댓글 내용은 지워서, 댓글 입력창을 비게 만든다!

더 간단히?

const handleTotalEnter = event => {
    if (event.key === 'Enter' && event.target.value !== '') {
      event.preventDefault();
      const repoArray = [...reviewArray];
      repoArray.push({ id: '익명', review: review });
      setReviewArray(repoArray);
      event.target.value = '';
    }
  };

조건을 합쳐 볼 수도 있다.

왜 기존의 array를 복사해오는가?

변화가 있을 때마다 render를 하는 것이다. 그러니 이전의 댓글들을 저장해두지 않으면 사라져버린다.

위부터 세 개 댓글을 화면에 직접 넣은 것이다. 이 기능과는 관련 없다.
댓글을 작성하면 초기값으로 넣어둔 것이 사라진다.
그렇기에 reviewArray에 지금까지의 댓글을 다 모아서 다시 그려주는 것이다.

draw

{reviewArray.map(data => (
                    <li className={styles.ghReview} key={data.id}>
                      <span className={styles.userId}>{data.id}</span>
                      <span className="text"> {data.review}</span>
                    </li>
                  ))}

이 부분은 컴포넌트로 따로 빼도 되고 직접 넣어줘도 된다.

  1. reviewArray에 있는 객체들(id와 댓글내용)을 html에 넣어준다.

완성!

profile
프론트엔드 개발자

0개의 댓글