TIL (240204)

Jtiiin:K·2024년 2월 5일
0

내일배움캠프

목록 보기
83/85
post-thumbnail

좋아요 알림

댓글 실시간 알림에 이어 좋아요에 대한 알림도 추가로 도전했다

시도 과정

처음 좋아요 알림을 생각했을 때
단순히 '댓글에 대한 코드를 복사해서 좋아요로 갈아끼우면 되겠지?' 라는 생각으로 접근했는데
그렇게 하면 알림 모달창에서 데이터를 map 으로 뿌려줄 때
좋아요에 대한 데이터 + 댓글에 대한 데이터를 합쳐서
하나의 데이터로 만들어줘야 하는데
두 데이터가 항상 같이 들어오는 것도 아니고
들어오는 순서에 따라 차례로 보여줘야 하기 때문에
이를 해결하다보니 분기처리 하기가 점점 더 어려워지고
좋아요 알림이 미궁으로 빠져갔다 @_@

해결책

계속 이리저리 삽질을 하다가 번뜩 생각난 것이
댓글과 좋아요에 대한 알림데이터를 alarm 테이블 한 곳에서 관리한다는 것
헤더에 있는 subscribe 코드가 똑같았다는 것!
결국 alarm 데이터에 type column 으로 댓글인지 좋아요인지 구분을 해주고 있기 때문에
기존에 있는 알림 코드에서 type만 구별해서 뿌려주면 되는 것이었다...!
alarmData가 통일되어서 쿼리키도 ['alarm', 'comment']['alarm', 'like'] 로
따로 관리하던 것을 그냥 ['alarm'] 로 통일시킬 수 있었다
쉽게 갈 수 있는 길을 빙빙 돌아 어렵게 가고 있었음.. 😥

그래도 삽질한 덕분에 실시간 알림 코드에 대해 좀 더 자세히 알 수 있었다!

리팩토링 (Custom Hook)

헤더에 useEffect 로 들어간 실시간 알림 코드가 생각보다 길어져서
커스텀훅으로 빼보았다!
return 값이 없는 커스텀 훅은 처음이라 좀 생소했지만
불러다쓰는 곳에서 그냥 함수처럼 꺼내쓰면 되는 거라
코드가 훨씬 보기 편해졌다

export const useAlarmSubscribe = (setAlarmState: (value: boolean) => void) => {
  const queryClient = useQueryClient();
  const { userId } = useSelector((state: RootState) => state.auth);
  const { alarmData } = useAlarm();

  useEffect(() => {
    if (!userId) return;
    const subscription: RealtimeChannel = supabase
      .channel('custom-filter-channel')
      .on(
        'postgres_changes',
        {
          event: 'INSERT',
          schema: 'public',
          table: 'alarms',
          filter: `received_id=eq.${userId}`,
        },
        (payload) => {
          queryClient.invalidateQueries({
            queryKey: ['alarms'],
          });
          setAlarmState(true);
        },
      )
      .on(
        'postgres_changes',
        {
          event: 'UPDATE',
          schema: 'public',
          table: 'alarms',
          filter: `received_id=eq.${userId}`,
        },
        (payload) => {
          queryClient.invalidateQueries({
            queryKey: ['alarms'],
          });
        },
      )
      .subscribe();
    return () => {
      subscription.unsubscribe();
    };
  }, []);

  useEffect(() => {
    if (alarmData?.length === 0) {
      setAlarmState(false);
    }
  }, [alarmData]);

  useEffect(() => {
    setAlarmState(alarmData?.length === 0 ? false : true);
  }, [alarmData?.length]);
};
// 사용하려는 컴포넌트에서 아래와 같이 불러다 쓰면 됨
useAlarmSubscribe(setAlarmState);
profile
호기심 많은 귀차니즘의 공부 일기

0개의 댓글