오늘은 좋아요 기능을 구현했다.
likeCount
에 넣기 위해 변수로 지정했다.interface LikeProps {
paramId: string | any;
course: CourseType | undefined;
}
const LikeBtn = ({ paramId, course }: LikeProps) => {
const [like, setLike] = useState(false);
const courseLikes = course && course?.likes;
const [likeCount, setLikeCount] = useState<number | any>(0);
likeCount
의 내용이 변경되는 코드를 작성한다. const submitLike = async () => {
if (!authService.currentUser) {
setLike(false);
alert("좋아요는 로그인 후 이용가능합니다.");
return;
}
if (like === true) {
setLike(false);
setLikeCount(likeCount - 1);
} else if (like === false) {
setLike(true);
setLikeCount(likeCount + 1);
}
};
likeCount
state에 현재 firestore에 저장된 좋아요 수를 업데이트하고, 좋아요 한 사용자라면 좋아요를 했다는 표시를 해주도록 작성했다. useEffect(() => {
setLikeCount(courseLikes);
const likeUser = course?.likesID.find((user) => user === currentId);
if (likeUser) {
setLike(true);
} else {
setLike(false);
}
}, [courseLikes, authService.currentUser]);
☄️ Trouble Shooting
하지만, 여기서 오류가 하나 있었는데,
좋아요 버튼을 눌렀을 때, firestore안에서 좋아요 수만 바로 업데이트 되지 않고, 버튼을 다시 눌러야지만 반영이 되는 오류가 발생했다.
const [like, setLike] = useState(false);
const [likeCount, setLikeCount] = useState<number | any>(0);
const submitLike = async () => {
if (!authService.currentUser) {
setLike(false);
alert("좋아요는 로그인 후 이용가능합니다.");
return;
}
if (like === true) {
setLike(false);
setLikeCount(likeCount - 1);
await updateDoc(courseRef, {
likes: likeCount,
likesID: arrayRemove(currentId),
});
} else if (like === false) {
setLike(true);
setLikeCount(likeCount + 1);
await updateDoc(courseRef, {
likes: likeCount,
likesID: arrayUnion(currentId),
});
}
};
이 문제는 state가 새롭게 렌더링 될 때 바뀌는데, lifecycle 기준으로 redering이 아직 일어나지 않아 likeCount
값이 변화되지 않은 상태로 updateDoc
이 실행되었기 때문이었다.
그러므로, like
, likeCount
가 변화되었을 때, 리렌더링하여 바뀐 likeCount
값이 업데이트 될 수 있도록,
아래와 같이 useEffect
안에 updateDoc
로직을 넣음으로써 해결할 수 있었다.
import { arrayRemove, arrayUnion, doc, updateDoc } from "firebase/firestore";
import { authService, dbService } from "../../utils/firebase";
const courseRef = doc(dbService, "courses", paramId);
const currentId = authService.currentUser?.uid;
useEffect(() => {
const updateLikes = async () => {
if (like) {
await updateDoc(courseRef, {
likes: likeCount,
likesID: arrayUnion(currentId),
});
} else {
await updateDoc(courseRef, {
likes: likeCount,
likesID: arrayRemove(currentId),
});
}
};
updateLikes();
}, [like, likeCount]);
튜터님의 피드백으로 위와 같이 수정했더니, 좋아요 수가 firestore에 바로바로 반영이 되어 해결할 수 있었다.
⭐ 컴포넌트는 return하는 부분에서 렌더링 된다. useEffect에서 의존성 배열에 값을 넣으면 렌더링 되는 부분에서 의존성배열 안의 값이 바뀔 때 다시 렌더링이 되는데, 의존성 배열 안의 값이 이전값과 비교해서 바뀌었다면 바뀐 값을 기준으로 실행된다.