[TIL] 230824

이세령·2023년 8월 24일
0

TIL

목록 보기
89/118

Nextjs

프로젝트 구현

좋아요 추가 및 취소

좋아요는 사용자와 상호작용하는 부분이기 때문에 use client로 클라이언트 컴포넌트로 구성하였으며 연속 이벤트로 과부하가 발생할 가능성이 있기 때문에 lodash라이브러리를 사용하여 thorottling을 적용했다.
table에 해당 영화가 존재하는지, 로그인된 유저가 좋아요를 했는지에 따라 다른 로직이 적용된다.

const { data: currentMovieLikeData } = useQuery<any>({
    queryKey: ['movieLikes', props.movieid],
    queryFn: async () => {
      const response = await supabase.from('movielikes').select('*').eq('movieid', props.movieid);
      return response.data;
    },
    enabled: Boolean(props.movieid) // movieid가 있을 때만 요청
  });

  const { userInfo } = useUserInfoStore();

  const mutation = useMutation(
    async () => {
      const { data: likesTable } = await supabase.from('movielikes').select('*').eq('movieid', props.movieid);

      if (likesTable?.length) {
        if (likesTable[0]?.user_id.includes(userInfo.id)) {
          const { data: users } = await supabase.from('movielikes').select('user_id').eq('movieid', props.movieid);
          const newUsers = users![0].user_id.filter((id: string) => id !== userInfo.id);
          await supabase.from('movielikes').update({ user_id: newUsers }).eq('movieid', props.movieid);
        } else {
          const { data: users } = await supabase.from('movielikes').select('user_id').eq('movieid', props.movieid);
          const newUsers = [...users![0].user_id, userInfo.id];
          await supabase.from('movielikes').update({ user_id: newUsers }).eq('movieid', props.movieid);
        }
      } else {
        const newUsers = { movieid: props.movieid, user_id: [userInfo.id] };
        await supabase.from('movielikes').insert(newUsers);
      }
    },
    {
      // 성공 시에 캐시 업데이트
      onSuccess: () => {
        queryClient.invalidateQueries(['movieLikes', props.movieid]);
      }
    }
  );
  • debounce vs thorottling
    debounce는 이벤트가 끝날 때까지 기다렸다가 시작하고 throttling은 이벤트가 시작되면 일정 주기로 계속 실행한다.
    성능 개선면에서는 debounce가 좋지만, 좋아요같이 즉시 결과를 요하는 기능에서는 throttling을 사용하는 것이 좋다.

  • thorottling 적용
    mutate대신 mutateAsync를 적용하여 비동기 작업이 완료되어야 다음 버튼을 받을 수 있도록 만들었다.

const likeButtonHandler = throttle(
    async () => {
      if (userInfo.id) {
        await mutation.mutateAsync();
      } else {
        alert('로그인 해주세요!');
      }
    },
    1000, // 스로틀링 간격 (여기서는 1000ms)
    { trailing: false } // 마지막 호출 후 추가 호출 방지
  );

Creating multiple root layouts

다른 경로의 root layout을 만들고 싶을때에는 route에 영향을 받지않도록 폴더명을 (shop)으로 만들고 그 아래에 원하는 경로로 만들면된다.

  • (shop)
    - layout.tsx
    - new
    이런 식으로 만들면 /new 경로로 만들 수 있고 new 경로의 root layout은 (shop)layout.tsx가 된다.

tanstack query

mutateAsync

mutate는 비동기 작업이 완료되면 onSuccess or onError 콜백함수를 return하는데 mutateAsync는 Promise를 반환하여 해당 비동기 작업이 끝날때까지 대기하고 결과를 받을 수 있다.

profile
https://github.com/Hediar?tab=repositories

0개의 댓글