![[React] 좋아요 기능 버그 해결 및 서버 데이터 활용](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn9XvB%2FbtsLs2SSvXD%2FpX4jJqjYsN3Kvm6kVeCH9K%2Fimg.jpg)
들어가며
경북대 축제 웹사이트를 개발하면서 부스별 좋아요 기능을 구현했다.
개발 초기에는 단순해 보였던 좋아요 기능이었지만, 실제 서비스 중에 예상치 못한 버그들이 발견되었다.
서비스 오픈 직후, 사용자들로부터 두 가지 주요 문제점이 보고되었다.
- 새로고침 시 좋아요 수가 2개씩 증가하는 현상
- 좋아요를 클릭한 후 페이지를 새로고침하면 좋아요 수가 예상보다 증가
- 여러 번 새로고침할 때마다 계속해서 숫자가 비정상적으로 증가
- 화면에 표시되는 좋아요 수와 서버의 실제 데이터 불일치
- 동일한 부스의 좋아요 수가 목록과 상세 페이지에서 다르게 표시
- 실제 서버에 저장된 좋아요 수와 화면에 표시되는 수가 일치하지 않음
원인 분석
클라이언트 계산
문제가 된 코드를 살펴보자.
<Heart
num={likeAble ? num + 1 : num} // 컴포넌트에서 직접 계산
likable={likeAble}
onClick={handleLikeBtnClick}
/>
첫 번째 문제의 원인은 컴포넌트 레벨에서 좋아요 수를 직접 계산하는 방식에 있었다.
좋아요 상태가 true일 때 기존 숫자에 1을 더하는 방식은 아래와 같은 문제를 발생시켰다.
- 이미 증가된 숫자에 다시 1을 더하는 중복 계산 발생
- 서버의 실제 데이터와 독립적으로 동작하는 클라이언트 계산
- 새로고침 시 이전 상태값을 고려하지 않은 계산 수행
서버 데이터 미활용
기존 코드는 서버의 응답 데이터를 효과적으로 활용하지 못했다.
const handleLikeBtnClick = useCallback(() => {
boothService.updateLikesByBoothId(visitorId, category, boothId).then(() => {
setLikeable((likeable) => !likeable); // 서버 응답 무시
});
}, [boothId, visitorId, category]);
두 번째 문제의 핵심은 서버의 응답을 무시한 채 클라이언트에서 상태를 독립적으로 관리했다는 점이다.
좋아요 API를 호출한 후, 서버에서 받은 최신 좋아요 수는 사용하지 않고 단순히 상태 토글만 수행했다.
이로 인해 실제 서버의 데이터와 클라이언트의 상태가 점점 어긋나게 되었다.
해결 과정
상태 설계 개선
먼저 좋아요 수를 관리하기 위한 별도의 상태를 추가했다.
const [likenum, setLikenum] = useState<IUpdateLike>({ likeNum: num });
서버로부터 받은 좋아요 수를 관리하기 위한 첫 번째 단계로 위의 코드를 추가했다.
더 이상 컴포넌트에서 임의로 계산하지 않고, 서버의 데이터를 사용하는 방식으로 전환했다.
서버 데이터 동기화
좋아요 클릭 핸들러를 수정해 서버 응답을 활용했다.
const handleLikeBtnClick = useCallback(() => {
boothService.updateLikesByBoothId(visitorId, category, boothId).then((data) => {
setLikenum(data.data); // 서버 응답으로 상태 업데이트
setLikeable((likeable) => !likeable);
});
}, [boothId, visitorId, category]);
이제 서버에서 받은 최신 좋아요 수로 상태를 업데이트하므로, 클라이언트와 서버 간의 데이터 일관성이 보장된다.
단순해 보이는 좋아요 기능이더라도, 상태 관리와 데이터 동기화에 대한 신중한 접근이 필요하다는 것을 느꼈다. 특히 서버와의 통신이 필요한 기능에서는 클라이언트 쪽에서 임의로 계산하는 것을 최소화하고, 서버의 데이터를 사용하는 것이 안전함을 다시 한 번 상기하는 시간이었다.
'Web, Front-end > 문제 해결' 카테고리의 다른 글
[React] Scroll event부터 Intersection Observer API까지 (1) | 2025.03.06 |
---|---|
테스트 커버리지가 제대로 인식되지 않는 현상 해결 (0) | 2025.01.19 |
[Javascript] 브라우저 팝업 차단으로 인한 문제와 해결책 (0) | 2024.12.01 |
[Typescript] 사진과 영상을 FormData로 서버에 전송하기 (6) | 2024.09.19 |
컴퓨터 전공 관련, 프론트엔드 개발 지식들을 공유합니다. React, Javascript를 다룰 줄 알며 요즘에는 Typescript에도 관심이 생겨 공부하고 있습니다. 서로 소통하면서 프로젝트 하는 것을 즐기며 많은 대외활동으로 개발 능력과 소프트 스킬을 다듬어나가고 있습니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!