내가 쓴 리뷰에 댓글이 달리면 실시간 알림이 오는 기능!
어제 알림을 띄우는 것까지는 성공했으니
추가로 해야할 것에 대해 먼저 생각해봤다
1. 알림을 어떻게 보여줄까?
2. 어디에 알림버튼을 둘까?
3. 여러 개의 알림을 어떻게 하나씩 읽음처리할까?
4. 모든 알림을 어떻게 한 번에 읽음처리할까?
프로젝트가 거의 막바지라 초반부처럼 일단 코드를 냅다 짜면서 만들기에는
다른 코드들까지 많이 건들게 될 것 같아서
위의 네가지를 어떻게 할지 미리 생각해보는 데만
오전 시간을 다 쓴 것 같다 🤔
그렇다면 드롭다운을 펼칠 버튼은 어디에 두는 것이 좋을까?
처음부터 헤더를 고려한 것은 아니지만
어느 페이지에 있어도 실시간 알림을 확인할 수 있는 곳은
헤더밖에 없는 것 같아서 헤더에 두기로 했다
(모든 페이지에 있어서 unmount 되지 않는 컴포넌트이기도 함)
테이블에 read column을 만들어서 초기값을 false로 지정해두고
알림을 클릭할 때마다 read : true 로 수정하자!
모두 읽음 버튼을 만들어서 모든 알림을 한번에 read: true 로 수정!
useAlarm이라는 커스텀 훅에 Query로 서버통신하기
커스텀 훅에서 읽어온 알림데이터 (alarmData)를 가져와서
alarm 테이블에 변화가 생겼을 때(INSERT,UPDATE) 알림 아이콘의 상태값을 바꾸고
아이콘이 클릭됐을 때 펼쳐지는 드롭다운에 알림 내용을 넣어줬다
💥 문제 💥
알림을 모두 확인한 후 alarmData가 빈배열이 되면
다시 알림 아이콘을 돌려놔야 하는데 이 부분이 계속 바뀌질 않았다
useEffect의 dependency array에 alarmData를 넣어도
해당 값이 변하는 걸 알아채지 못했다
결국 useEffect를 하나 더 만들어서 alarmData를 따로 담아줬더니 해결!
(alarmData를 가져오는 useQuery가 비동기로 실행돼서 그런듯!)
🔽 내가 생각한 코드 🔽
.on(
'postgres_changes',
{
event: 'UPDATE',
schema: 'public',
table: 'alarm',
filter: `received_id=eq.${userId}`,
},
(payload) => {
queryClient.invalidateQueries({
queryKey: ['alarm', userId],
});
// 안되던 부분
if(alarmData?.length===0){
setAlarmState(false)
}
},
)
🔽 해결된 코드 🔽
// header.tsx
useEffect(() => {
if (!userId) return;
const subscription: RealtimeChannel = supabase
.channel('custom-filter-channel')
.on(
'postgres_changes',
{
event: 'INSERT',
schema: 'public',
table: 'alarm',
filter: `received_id=eq.${userId}`,
},
(payload) => {
queryClient.invalidateQueries({
queryKey: ['alarm', userId],
});
// 알림 아이콘 변경
setAlarmState(true);
},
)
.on(
'postgres_changes',
{
event: 'UPDATE',
schema: 'public',
table: 'alarm',
filter: `received_id=eq.${userId}`,
},
(payload) => {
queryClient.invalidateQueries({
queryKey: ['alarm', userId],
});
},
)
.subscribe();
return () => {
subscription.unsubscribe();
};
}, []);
// alarmData 가 빈배열 일 때 (= 새 알림이 없을 때)
useEffect(() => {
if (alarmData?.length === 0) {
// 알림 아이콘 변경
setAlarmState(false);
}
}, [alarmData]);
한 리뷰에 여러 개의 댓글이 달릴 경우 한 번만 리뷰페이지에 방문하면
사실상 해당 리뷰에 대한 댓글을 모두 확인하는 것인데
이를 어떻게 처리할지 아직 고민 중이다
추가로 좋아요에 대한 알림과 댓글이 실시간으로 화면에 반영될 수 있도록 하는 것도 해볼 예정!
빡세다 빡세 😣