새로고침하면 내가 클릭했던 하트가 초기화되는 문제가 발생했다.
좋아요 상태를 지속적으로 유지하기 위해서는 브라우저의 localStorage나 cookie를 사용해야 했고, localStorage를 사용하기로 했다.
기존에 만들었던 updateLikes 함수에 localStorage.setItem('likedSongs', JSON.stringify(likedSongs)); 코드를 추가하고,
useEffect(() => {
// 로컬 스토리지에서 좋아요 상태 불러오기
const storedLikedSongs = localStorage.getItem('likedSongs');
if (storedLikedSongs) {
setLikedSongs(JSON.parse(storedLikedSongs));
}
getSongs()
.then((data) =>
setSongs(data.slice().sort((a: Song, b: Song) => b.likes - a.likes))
)
.catch((error) => {
console.error('Error fetching songs:', error);
});
}, []);
라고 적었으나 곡 A의 좋아요를 클릭하면 빈 배열이고, 그 다음 곡 B의 좋아요를 누르면 A의 좋아요가 localStorage에 저장되는 걸 발견했다.
로컬 스토리지의 데이터를 불러오기 전에 초기 상태로 저장된 빈 배열 []이 저장되기 때문이었고, 초기 렌더링 시에 로컬 스토리지에서 좋아요 상태를 불러오는 코드를 조건문으로 감싸서 처리했다.
useEffect(() => {
const storedLikedSongs = localStorage.getItem('likedSongs');
if (storedLikedSongs) {
setLikedSongs(JSON.parse(storedLikedSongs));
} else {
// 로컬 스토리지에 좋아요 상태가 없으면 빈 배열로 초기화
localStorage.setItem('likedSongs', JSON.stringify([]));
}
...그리고 다시 getSongs()
그러나 여전히 안되었고, useEffect에서 처리하는 게 아니라 애초에 useState에 담아놔야겠다는 결론이 났다.
const [likedSongs, setLikedSongs] = useState<number[]>(() => {
const storedLikedSongs = localStorage.getItem('likedSongs');
return storedLikedSongs ? JSON.parse(storedLikedSongs) : [];
});
그 다음 handleClick 함수에서 songs, likedSongs를 별도로 update해주고 정리해줬다.
const handleLikeClick = async (
songId: number,
title: string,
img: string,
album: string
) => {
try {
const isLiked = likedSongs.includes(songId);
const updatedSongs = updateLikesInSongs(songId, isLiked);
const updatedLikedSongs = updateLikedSongsList(songId, isLiked);
await updateLikesOnServer(songId, title, img, album, updatedSongs);
updateState(updatedSongs, updatedLikedSongs);
} catch (error) {
console.error('Error updating likes:', error);
}
};
