React Query (심화)

Jinwoo Ma·2023년 12월 6일

React

목록 보기
17/17
post-thumbnail

SWR (Stale-While-Revalidate)

stale : 신선하지 않은, 오래된

  • 신규 데이터가 도착하는 동안 기존 캐싱된 데이터를 사용하는 전략

Cache Data는 어디에 보관할까?

  • QueryClientProvider는 React Context API를 내부적으로 사용한다.
  • QueryClientProvider의 자식으로 있는 모든 컴포넌트들은 캐시 데이터에 접근할 수 있다.
  • 페이지 컴포넌트 외부에 상태가 존재하므로 캐시 데이터는 전역 상태로 볼 수 있다.

React Query vs Tanstack Query

Tanstack query 란?

React Query의 v4부터 변경된 라이브러리 명

yarn add @tanstack/react-query

v4부터는 query key를 반드시 배열 형태로 사용해야 한다.

useQuery(["todos"], getTodos)

React Query의 lifecycle

active(fetching, fresh, stale) -> inactive -> deleted

  • 캐시 데이터에 대한 life cycle
  • 각각의 캐시 데이터마다 생명 주기를 갖고 있다.

active : 캐시 데이터를 사용하고 있는 화면
fetching => fresh (새거) / stale (헌거)
stale => 계속 queryFn을 실행하며 fresh data를 가져온다.

inactive : 현재 화면이 캐시 데이터를 사용하지 않는다.

React Query default config

  • staleTime: 유통기한 => infinity ? stale 값이 없다. 항상 fresh. 기본 설정은 0 (항상 stale한 데이터를 사용)
  • refetchOnMount: false ? 마운트가 됐을 때 최초에만 호출한다. (다시 페이지를 돌아오면 호출 x)
  • refetchOnWindowFocus: 다른 곳을 클릭했다 브라우저 창을 클릭하면 refetch
  • refetchOnReconnect: 네트워크가 끊긴 후 재연결 됐을 때 refetch
  • cacheTime: 사용하지 않는 캐시 데이터를 언제 삭제할 것인가? (inactive 데이터)
  • retry: 재시도 횟수(서버 상태가 정상이 아닐 경우가 있다. => 바로 error를 띄우는 것이 아니다.)

isLoading vs isFetching

isLoading : 새로운 캐시 데이터를 서버에서 받고 있는가?

캐시 데이터가 있는 경우 isLoading은 false, isFetching은 true

isFetching : 서버에서 데이터를 받고 있는가?

useQuery에서 자주 사용하는 옵션들

enabled

useQuery(["todos"], getTodos, { enabled: true })

boolean type: true or false
true인 경우에만 queryFn 실행
enabled 옵션이 없을 경우, 기본값으로 true 로 생각하고 useQuery 자동실행됨.

Disabling/Pausing Queries (이벤트 발생 시에만 수동 실행)

const { data, refetch } = useQuery(["todos"], getTodos, {
  enabled: false
});

return (
	<div>
    <button onClick={() => refetch()}>데이터 불러오기</button>
  </div>
);

Dependent Queries (useQuery 2개 이상, 순서가 필요할 때)

// Get the user
const { data: user } = useQuery({
  queryKey: ['user', email],
  queryFn: getUserByEmail,
})

const userId = user?.id

// Then get the user's projects
const {
  status,
  fetchStatus,
  data: projects,
} = useQuery({
  queryKey: ['projects', userId],
  queryFn: getProjectsByUser,
  enabled: !!userId
})

userId가 들어와야 쿼리가 실행된다.

select

queryFn 에 의해 리턴된 값을 변형시킨 후에 useQuery 의 리턴 data로 넘겨준다.

...
  const { data } = useQuery(['user'], fetchUser, {
    select: (user) => user.username,
  })
  return <div>Username: {data}</div>
...

0개의 댓글