Select Option과 Re-fetching, 그리고 Polling

gyojinnK·2024년 7월 19일

React-query

목록 보기
7/9
post-thumbnail

Filtering with the select option

select option을 이용한 filter가 유용한 이유

  • 리액트 쿼리는 실제로 이를 최적화하기 때문(불필요한 계산을 줄임)

  • 상세 동작

    • 리액트 쿼리는 select 함수의 삼중 등호 비교를 수행
    • 데이터가 마지막으로 데이터를 검색했을 때와 동일하고 select 함수가 동일한 경우 select 함수를 다시 실행시키지 않음 -> 최적화
  • 이는 select 함수를 위한 안정적인 함수가 필요하다는 의미

    • 매번 변경되는 익명 함수를 사용할 수 없음
      • 삼중 등호 비교가 실패하게 될 것이기 때문

        이때, 익명 함수에서 안정적인 함수를 만들고 싶다면
        useCallback 함수 사용

Re-fetching

Refetching은 왜? 그리고 언제 사용하는가?

  • 일반적으로 백그라운드 prefetching을 사용하먄 오래된 데이터를 서버에서 업데이트할 수 있다.
  • 기본적으로 오래된 쿼리는 특정 조건에 따라 백그라운드에서 자동으로 리페치
    • 쿼리의 새 인스턴스가 마운트될 때 -> 해당 키가 포함된 쿼리가 처음으로 호출될 때
    • 리액트 컴포넌트를 마운트할 때마다 쿼리 호출
    • 윈도우에 초점이 다시 맞춰질 때
    • 네트워크가 다시 연결된 경우, 오래된 데이터가 업데이트되었는지 확인을 위해서.
    • 구성된 refetchInterval이 경과한 경우
      • 이는 사용자 작업이 없는 경우에도 데이터가 최신 상태로 유지되도록 서버를 주기적으로 리페치하여 데이터를 가져오려는 경우

Refetching 방법

  • refetchOnMount, refetchOnWindowFocus, refetchOnReconnect, refetchIntaval

  • 명령형으로 refetch (in useQuery)

Suppressing Re-fetch (리페치 억제)

  • stale time 늘리기
    • 캐시 데이터가 오래된(stale) 경우에만 리페치를 트리거하기 때문
  • boolean 옵션인 refetchOnMount, refetchOnWindowFocus, refetchOnReconnect 중 하나 또는 모두 끄기

리페치 억제는 자주 변경되지 않고 약간 오래되어도 사용자에게 큰 영향을 미치지 않는 데이터에 대해서만 수행해야함.
네트워크 호출을 효과적으로 줄이는가? 스스로 판단하기


Global Re-fetching

전역에서 리페치 옵션을 관리한다. 필요에 따라 개인화된 옵션을 추가로 설정할 수 있다.

refetching 옵션을 전역에서 관리하고 적용 방법

  • mutation 수행한 후 데이터를 무효화 -> 리페치 트리거
  • Global 옵션은 src/react-query/queryClient.ts

Polling과 Auto Refetching

useQueryrefetchInterval 옵션을 사용하여 폴링 간격 설정

  const { data: appointments = fallback } = useQuery({
    queryKey: [queryKeys.appointments, monthYear.year, monthYear.month],
    queryFn: () => getAppointments(monthYear.year, monthYear.month),
    select: (data) => selectFn(data, showAll),
    refetchOnWindowFocus: true,
    refetchInterval: 60000, // 1분 간격으로 데이터 리페칭
    ...commonOptions,
  });

Summary

필터링을 위한 select option

  • 리액트 쿼리 캐싱을 활용하고 데이터를 다시 필터링하지 않으려면, 삼중 등식 테스트에서 살아남을 수 있는 함수여야 한다.
  • 그래서 함수가 안정적인지 확인하기 위해 리액트 useCallback을 사용
    const selectFn = useCallback(
      (unfilteredStaff: Staff[]) => {
        if (filter === "all") return unfilteredStaff;
        return filterByTreatment(unfilteredStaff, filter);
      },
      [filter]
    );

Re-fetch 옵션과 Suppressing Re-fetch 옵션

  • 해당 옵션들은 전역적으로 추가한 다음, 특정 useQueries 및 prefetch 쿼리 호출에서 Overloading
// 전역 queryClient에 옵션 설정
export const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 600000, // 10분
      gcTime: 900000, // 15분
      refetchOnWindowFocus: false,
    },
  },
  ...
});
// 특정 useQueries 및 prefetch 쿼리 호출에서 Overloading
const commonOptions = {
  staleTime: 0,
  gcTime: 30000, // 5분(기본값)
};
...
  const { data: appointments = fallback } = useQuery({
    queryKey: [queryKeys.appointments, monthYear.year, monthYear.month],
    queryFn: () => getAppointments(monthYear.year, monthYear.month),
    select: (data) => selectFn(data, showAll),
    refetchOnWindowFocus: true,
    refetchInterval: 60000, // 1분
    ...commonOptions,
  });
...

폴링

refetchInterval 옵션

서버에서 데이터가 변경되었을 경우를 대비해 일정 간격으로 데이터를 리페치

profile
기록하고 꺼내보고

0개의 댓글