
해당 부분을 postActions 컴포넌트로 분리했다.
import React from "react";
import FavoriteBorder from "@mui/icons-material/FavoriteBorder";
import ChatBubbleOutlineIcon from "@mui/icons-material/ChatBubbleOutline";
import TelegramIcon from "@mui/icons-material/Telegram";
import BookmarkBorderIcon from "@mui/icons-material/BookmarkBorder";
import styles from "../styles/post.module.css";
function PostActions() {
return (
<div className={styles.icons_container}>
<div>
<FavoriteBorder className={styles.icon} />
<ChatBubbleOutlineIcon className={styles.icon} />
<TelegramIcon className={styles.icon} />
</div>
<div>
<BookmarkBorderIcon className={styles.icon} />
</div>
</div>
);
}
export default PostActions;
아이콘을 클릭하면, handlePostLike 이벤트가 발생한다.
<FavoriteBorder className={styles.icon} onClick={handlePostLike} />
handlePostLike 이벤트 메서드는 다음과 같이 구현했다.
const handlePostLike = async () => {
try {
const response = await axios.post('/api/postlike', {
userId: userId,
postId: postId
});
console.log(response.data);
} catch (error) {
console.error('Error liking the post:', error);
}
};

데이터베이스에 사용자id 와 포스트id가 정상적으로 저장되는 것을 확인했다.

그런데, 좋아요를 눌러도 icon이 변하지 않았다. 😕
당연하다.
아이콘은 여전히 <FavoriteBorder /> 이거 하나다.
사용자가 해당 포스트에 좋아요를 눌렀는지 확인하는 메서드를 구현했다.
const [isLiked, setIsLiked] = useState(false);
useEffect(() => {
const fetchLikeStatus = async () => {
try {
const response = await axios.get('/api/postlike/status', {
params: { userId: userId, postId: postId }
});
setIsLiked(response.data);
} catch (error) {
console.error('Error fetching like status:', error);
}
};
fetchLikeStatus();
}, [userId, postId]);
setIsLiked(response.data); 에서 응답이 true라면, isLinked = true가 된다.
isLinked = true일때, <FavoriteBorder /> 대신 <FavoriteIcon />가 출력되어야한다.
isLiked ? (
<FavoriteIcon className={styles.icon} />
) : (
<FavoriteBorder className={styles.icon} onClick={handlePostLike} />
)}

그러면 이렇게 좋아요 아이콘이 바뀌지 않는다.
여전히 <FavoriteBorder /> 가 출력된다.

모달창을 껐다가 켜야 <FavoriteIcon /> 가 출력된다.
useEffect(() => {
const fetchLikeStatus = async () => {
try {
const response = await axios.get('/api/postlike/status', {
params: { userId: userId, postId: postId }
});
setIsLiked(response.data); // 백엔드에서 받아온 좋아요 상태를 설정
} catch (error) {
console.error('Error fetching like status:', error);
}
};
fetchLikeStatus();
}, [userId, postId]);
useEffect 가 처음 로드될 때 좋아요 상태를 가져오기 때문이다.
좋아요 아이콘을 클릭하면, isLiked 상태가 즉시 변경되도록 구현하변 되지 않을까?
const handlePostLike = async () => {
try {
const response = await axios.post('/api/postlike', {
userId: userId,
postId: postId
});
console.log(response.data);
setIsLiked(true); // 좋아요 상태를 즉시 true로 만든다
} catch (error) {
console.error('Error liking the post:', error);
}
};

<FavoriteBorder /> 아이콘을 클릭하면, 아이콘이 바로 <FavoriteIcon /> 로 바뀐다. 굿👍
하지만, 모달창을 켤 때,
<FavoriteBorder /> 가 보였다가, <FavoriteIcon />로 바뀌는 것을 확인하고 말았다.
async 데이터를 가져오는 시간이 필요하기 때문인 것 같다.
모달창을 띄울 때, useEffect로 좋아요 상태를 호출하기 때문이다.
모달창을 띄울 때, 이미 좋아요 상태를 가지고 있어야할 것 같다.
그럼, 부모 컴포넌트에서 isLiked 상태를 가져와야하나? 테스트 해보면 되겠지...
부모 컴포넌트에 좋아요 상태를 가져오는 메서드를 추가했다.
useEffect(() => {
const fetchLikeStatus = async () => {
if (loggedInUser && postModal) {
try {
const response = await axios.get('/api/postlike/status', {
params: { userId: loggedInUser.id, postId: postModal.postId }
});
setIsLiked(response.data);
} catch (error) {
console.error('Error fetching like status:', error);
}
}
};
fetchLikeStatus();
}, [loggedInUser, postModal]);
<PostActions postId={postModal.postId} userId={loggedInUser.id} isLiked={isLiked} setIsLiked={setIsLiked} />
❗부모 컴포넌트에서 상태를 받아오므로, 자식 컴포넌트에서는 axios 함수를 뺐다.

됐다. 진짜 됐는데, 사진으로만 첨부하니까 잘 모르겠네...
다음에는 영상으로 따오던지 해야겠다.
북마크도 동일한 방식으로 진행하면 될 것 같다.