리팩토링 기간에 완성하게 된 댓글 수정기능!
일단 다음과 같은 과정을 통해 해당 댓글의 작성자일 때만 수정하기
버튼과 삭제하기
버튼이 보이게 만들었다.
- postId를 통해 해당 게시글에 작성된 댓글을 조회하기 위해 서버에 GET 요청 보냄
- 이 때 유저의 token을 함께 보냄(Axios instance 활용)
- 해당 댓글의 작성자인 경우 서버에서 response의
isAuthor
값을 true로 보내줌
그 다음 useState 훅을 이용해 현재 댓글을 수정하는 중인지 나타내는 상태값(isEdit)과 그 상태를 바꿔주는 함수를 만들어주었다.
const [isEdit, setIsEdit] = useState(false);
내가 구현하고 싶었던 모습은 아래와 같았다.
수정하기
버튼을 누르면isEdit
값이 true로 바뀜- 댓글 내용 부분이 댓글을 수정할 수 있는 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>
)}
자바스크립트의 이벤트 플로우는 비교적 최근에 알게 된 개념인데 이렇게 스터디에서 이론적으로 공부한 내용을 기능 구현에 직접 적용해보니까 기억에도 훨씬 더 잘 남는다. 고민 많았던 기능 구현에 성공한 기쁨은 덤🥰✨
독서기록 프로젝트에서 워낙 새롭게 알게된 것들이 많아서 임시저장글은 쌓여가고...😂