음악 추천 리스트에서 + 추가 버튼을 누르면 현재 유저의 재생 목록 테이블에 데이터가 추가되어야 하는데 고려해야 할 부분이 있다.
데이터가 있는지 판단하는 이유는 재생 목록에 추가하는 노래 id를 배열에 담기 때문에 한 번이라도 노래를 추가하여 재생한 적이 없다면 재생목록 테이블에 유저의 현재 재생 목록은 없다. (재생 목록 데이터가 있어야 그 데이터의 노래 컬럼에 배열로 재생할 노래를 담을 수 있다)
그렇기 때문에 먼저 이 유저가 현재 재생 목록을 가졌는지 판단 후 insert 또는 update를 해야 한다.
사실 회원가입 할 때 유저의 현재 재생 목록을 가지도록 재생 목록 테이블에 빈 값으로 insert를 하는 건 어떨지 고민도 했다.
만약 이 방법으로 한다면 추가할 때마다 재생 목록이 있는지 판단하는 요청을 supabase에 보내지 않아도 되기 때문에 리소스 낭비를 줄일 수 있을 것 같다는 생각이 든다.
지금은 데이터를 추가할 때 판단하고 추가하도록 구현했다.
이후에 팀원들과 논의해 보고 어떤 방식이 더 좋은지 고민해 보는 것도 좋을 것 같다.
구현
먼저 유저가 재생 목록을 가지고 있는지 확인한다.
export const getCurrentMusicData = async (userId: string): Promise<PlaylistCurrent[]> => {
try {
const { data } = await supabase.from("playlistCurrent").select("currentId, userId, currentMusicIds").eq("userId", userId);
return data as PlaylistCurrent[];
} catch (error) {
console.error(error);
return [];
}
};
userInfo는 zustand에 저장되어 있다. 이 데이터는 로그인할 때 담긴다.
쿼리에서 enabled로 userInfo.uid 가 있으면 쿼리를 실행하도록 하였다.
이렇게 하면 불필요한 요청을 방지할 수 있다.
만약 이 설정을 하지 않으면 usreInfo에 zustand가 값을 가져오기 전에 useQuery가 실행되어 버려서 원하는 결과를 받지 못할 수 있다. 그렇기 때문에 userInfo에 의존하도록 만들어 주는 게 좋다.
const { userInfo } = useStore();
const { data: playListCurrent } = useQuery({
queryFn: () => getCurrentMusicData(userInfo.uid),
queryKey: ["playListCurrent"],
enabled: !!userInfo.uid
});
데이터가 있는지에 따라서 로직을 insert와 update로 분기했다.
playListCurrent 가 있으면 유저의 재생 목록이 있다는 것이므로 insert를, 없다면 update를 실행한다.
또한, update 시에는 같은 노래가 이미 추가되어 있는지 판단한다.
const onClickAddCurrentMusicHandler = (userId: string, musicId: string) => {
if (userId === "") {
alert("로그인 후 사용할 수 있는 서비스입니다. 로그인 페이지로 이동합니다.");
router.replace("/login");
return;
}
if (playListCurrent && playListCurrent.length > 0) {
const currentList = playListCurrent[0].currentMusicIds;
if (currentList.find((el) => el === musicId)) {
alert("이미 추가된 노래입니다."); //이후에 삭제 예정
return;
}
currentList.push(musicId);
updateMutation.mutate({ userId, currentList });
} else {
insertMutation.mutate({ userId, musicId });
}
alert("현재 재생목록에 추가 되었습니다."); //이후에 삭제 예정
};
insert와 update를 수행하는 쿼리이다.
const insertMutation = useMutation({
mutationFn: insertCurrentMusic,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["playListCurrent"] });
}
});
const updateMutation = useMutation({
mutationFn: updateCurrentMusic,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["playListCurrent"] });
}
});
export const insertCurrentMusic = async ({ userId, musicId }: { userId: string; musicId: string }) => {
try {
await supabase
.from("playlistCurrent")
.insert([{ userId: userId, currentMusicIds: [musicId] }])
.select();
} catch (error) {
console.error(error);
}
};
export const updateCurrentMusic = async ({ userId, currentList }: { userId: string; currentList: string[] }) => {
try {
await supabase
.from("playlistCurrent")
.update({ currentMusicIds: [...currentList] })
.eq("userId", userId)
.select();
} catch (error) {
console.error(error);
}
};
결과
완성!
ui 작업도 곧 해야지..
'TIL' 카테고리의 다른 글
tailwind 로컬 서버랑 배포 서버의 css 우선순위가 왜 다르지? (2) | 2024.04.19 |
---|---|
상위 컴포넌트에서 하위 컴포넌트로 늦게 내려오는 문제 (0) | 2024.04.18 |
react/typescript input checkbox 전체 선택 구현 (0) | 2024.03.29 |
[tailwind css] 반응형 및 color 셋팅 (0) | 2024.03.29 |
[프로그래머스] 모의고사 (0) | 2024.03.28 |