이벤트 버블링과 useState를 활용한 댓글 수정하기 기능

Sujeong K·2023년 3월 1일
0
post-thumbnail

리팩토링 기간에 완성하게 된 댓글 수정기능!

일단 다음과 같은 과정을 통해 해당 댓글의 작성자일 때만 수정하기 버튼과 삭제하기 버튼이 보이게 만들었다.

  1. postId를 통해 해당 게시글에 작성된 댓글을 조회하기 위해 서버에 GET 요청 보냄
  2. 이 때 유저의 token을 함께 보냄(Axios instance 활용)
  3. 해당 댓글의 작성자인 경우 서버에서 response의 isAuthor 값을 true로 보내줌

그 다음 useState 훅을 이용해 현재 댓글을 수정하는 중인지 나타내는 상태값(isEdit)과 그 상태를 바꿔주는 함수를 만들어주었다.

const [isEdit, setIsEdit] = useState(false);

내가 구현하고 싶었던 모습은 아래와 같았다.

  1. 수정하기 버튼을 누르면 isEdit 값이 true로 바뀜
  2. 댓글 내용 부분이 댓글을 수정할 수 있는 input으로 변경
  3. 수정하기 버튼이 수정완료 버튼으로 변경

수정하기 클릭 시 input 창으로 변경

댓글 내용 부분을 input으로 변경하는 것은 isEdit 값과 삼항 연산자를 사용하여 구현했다. 이 때 input으로 바뀌었을 때 원래 댓글 내용이 value로 남아있도록 localContent로 넣어줬다! (isEdit이 false일 때는 그냥 원래 댓글 내용만 보이도록 props.content로 설정)

  const [localContent, setLocalContent] = useState(props.content); 

// ...생략

<CommentContent>
        {isEdit ? (
          <input
            value={localContent}
            onChange={(e) => setLocalContent(e.target.value)}
          />
        ) : (
          props.content
        )}
</CommentContent>

수정하기 클릭 시 버튼 글자 수정완료로 변경

여기에서 isEdit 값이 true 일 때만 수정완료 버튼으로 바뀌도록 하는 과정이 가장 고민이었다. isAuthor 값이 true 일 때만 수정하기 버튼과 삭제하기 버튼이 렌더링 되도록 이미 삼항연산자로 만들어 준 상태였는데 '그럼 삼항 연산자를 중첩해야하나' 고민하던 중, 정말 번뜩 스터디에서 공부했던 이벤트 버블링 개념이 떠올랐다.

✏️ 이벤트 버블링 : 하위 요소의 이벤트가 상위 요소의 이벤트 핸들러에 영향을 주는 현상

<CommentModifyButton onClick={() => setIsEdit(!isEdit)}>
            {isEdit ? (
              <span onClick={() => commentPatchMutation.mutate()}>
                수정완료
              </span>
            ) : (
              <span>수정하기</span>
            )}
</CommentModifyButton>

그래서 위와 같이 isEdit 값을 토글시키는 setIsEdit은 CommentModifyButton 태그에 등록해주고, isEdit 값이 true 일 때만 렌더링되는 수정완료 span 태그에 PATCH 요청을 보내는 mutation 함수를 등록했다.

이렇게 하면 isEdit 값이 true 일 때는 수정완료가 렌더링 되고 그 수정완료를 클릭하면 부모 요소인 CommentModifyButton에도 클릭 이벤트가 전파되기 때문에 자동으로 setIsEdit 함수가 실행된다! 그럼 isEdit 값이 다시 false가 되면서 수정하기 버튼으로 변경되고 input으로 되어있던 UI도 수정된 내용으로 바뀐다.

완성된 기능

      {props.isAuthor && (
        <div className="commentButton">
          <CommentModifyButton onClick={() => setIsEdit(!isEdit)}>
            {isEdit ? (
              <span onClick={() => commentPatchMutation.mutate()}>
                수정완료
              </span>
            ) : (
              <span>수정하기</span>
            )}
          </CommentModifyButton>
          <CommentModifyButton onClick={() => commentDeleteMutation.mutate()}>
            삭제하기
          </CommentModifyButton>
        </div>
      )}


자바스크립트의 이벤트 플로우는 비교적 최근에 알게 된 개념인데 이렇게 스터디에서 이론적으로 공부한 내용을 기능 구현에 직접 적용해보니까 기억에도 훨씬 더 잘 남는다. 고민 많았던 기능 구현에 성공한 기쁨은 덤🥰✨

독서기록 프로젝트에서 워낙 새롭게 알게된 것들이 많아서 임시저장글은 쌓여가고...😂

profile
차근차근 천천히

0개의 댓글