◼ React Query
React Query는 클라이언트 측에서 서버 상태 관리를 간편하고 효율적으로 도와주는 라이브러리입니다. 캐싱, 동기화, 백그라운드 업데이트 등을 자동으로 처리해주기 때문에 클라이언트와 서버 간의 데이터 전달과 관리가 편해집니다.
서버 상태 데이터는 비동기적으로 받아와야 하며, 로딩 중에는 로딩 화면을 보여주고, 에러 발생 시 이를 처리하고 사용자에게 안내해야 합니다. 또한, 서버 상태 데이터는 가능한 최신 상태를 유지해야 하며, 이는 사이트의 성격에 따라 주기적으로 업데이트될 필요가 있습니다. 이러한 특성 때문에 서버 상태 데이터를 관리하는 것은 복잡합니다. 기존의 Redux 같은 라이브러리에서는 이러한 관리를 쉽게 할 수 없었지만, 리액트 쿼리를 사용하면 각각 따로 처리해야 했던 부분들을 한 번에 처리할 수 있어 많은 이점을 제공합니다.
◼ React Query 출력해서 값을 살펴보자
// React Query는 useQuery 훅을 사용하여 작업합니다.
const data = useQuery({ queryKey: ['post'], queryFn: getPosts });
console.log(data); // 이미지 출력 결과
// queryKey: ['post'] - 쿼리를 고유하게 식별하기 위한 키입니다. 이 키를 사용하여 쿼리의 캐싱, 갱신 등을 관리합니다.
// queryFn: getPosts - 실제 데이터를 가져오는 함수입니다. 이 함수가 실행되어 데이터를 받아옵니다.
Query Status
실제 받아온 값의 유무를 확인합니다.출력값중 status 속성에서 확인 가능합니다.
값을 3가지로 결과를 나타냅니다.
pending : 데이터를 아직 받아오지 않았을때
error : 데이터 받아오는 중 에러가 났을대
success : 데이터 성공적으로 가지고 욌을때
Fetch Status
함수가 현재 실행중인지 아닌지를 fetchStatus 속성에서 확인이 가능합니다.
fetching: 쿼리 함수가 실행되는 중일 때.
paused: 쿼리 함수가 시작은 되었지만 실제로 실행되지 않는 상태(예: 네트워크가 오프라인일 때).
idle: 쿼리 함수가 어떤 작업도 하지 않는 상태(즉, fetching도 아니고 paused도 아닌 상태. 데이터를 다 받아와 완료상태일때)
◼ React Query 캐시
캐시라고 하면 임시저장소를 제일 먼저 생각합니다.
브라우저의 캐시 같은 개념인거죠. ReactQuery는 캐시의 기능이 있습니다.
const data = useQuery({ queryKey: ['post'], queryFn: getPosts });
//queryKey: ['post']
쿼리키를 이용해서 캐싱을 하며, 키를 가지고 저장된게 있는지 확인도 합니다.
그리고 데이터의 상태 또한 알수 있습니다.
Fresh: 백엔드에서 갓 받아온 후 신선한 상태.
Stale: 특정 시간이 지나 신선하지 않은 상태
Inactive: 컴포넌트가 언마운트되어 데이터가 사용되지 않는 상태.
캐시 관리
캐시의 관리는 ReactQuery가 자동으로 한다고 생각하면 됩니다. 불필요한 가비지 데이터도 ReactQuery가 자동으로 삭제하여 새로운 데이터을 받을수 있도록 합니다.
쿼리 컴포넌트가 언마운트 되어 해당 데이터가 쓰이지 않는 상황이 되면 데이터는 inactive 상태가 됩니다.
inactive 상태의 데이터는 가비지 컬렉션 타임(garbage collection time)이 지나면 캐시에서 삭제가 됩니다. 가비지 컬렉션 타임은 기본적으로 5분으로 설정되어 있는데, 이 역시 값을 변경할 수 있습니다.
Stale Time
데이터가 오래된 것으로 간주되는 시간을 의미합니다.리액트 쿼리에서 기본값은 0으로 설정되어 있어, 백엔드에서 받아온 데이터도 즉시 stale 상태가 됩니다.이는 매번 데이터가 필요할 때마다 refetch를 하게 만듭니다.사이트의 특성에 맞게 매번 refetch가 필요하지 않다면 stale time 값을 적절히 조정합니다
Garbage Collection Time
캐시에 저장된 데이터는 영구적으로 남아있지 않습니다.리액트 쿼리는 쿼리 컴포넌트가 언마운트되어 데이터가 사용되지 않으면 해당 데이터를 inactive 상태로 만듭니다.inactive 상태가 된 데이터는 기본적으로 5분 후에 캐시에서 삭제됩니다.이 시간은 garbage collection time으로 불리며, 필요에 따라 값을 변경할 수 있습니다.
ReFetch 상태
refetch는 다음 네 가지 상황은 자동으로 코드를 적지 않아도 발생합니다
새로운 쿼리 인스턴스가 마운트될 때
브라우저 창에 다시 포커스가 갈 때
네트워크가 다시 연결될 때
미리 설정된 refetch interval 시간이 지났을 때
이 동작은 각각 refetchOnMount, refetchOnWindowFocus, refetchOnReconnect, refetchInterval 옵션을 통해 변경 가능합니다.
효율적 데이터 페칭 특정 기능
Query Invalidation:쿼리 무효화(Query Invalidation)는 특정 이벤트 후에 데이터를 다시 요청하도록 할 수 있습니다. 이를 통해 데이터의 최신 상태를 유지할 수 있습니다.예를 들어, 포스트 작성을 완료한 후queryClient.invalidateQueries(['posts'])를 호출해 ['posts'] 쿼리를 무효화하고 데이터를 다시 가져오도록 할 수 있습니다.
Optimistic Updates:낙관적 업데이트(Optimistic Updates)를 통해 데이터 업데이트가 성공할 것이라고 가정하고 UI를 먼저 업데이트하여 사용자 경험을 향상시킬 수 있습니다.백엔드 요청이 실패하면 롤백(Rollback) 메커니즘을 통해 원래 상태로 되돌립니다.
Query Key Structuring:쿼리 키를 구조화하여 여러 변수를 포함할 수 있습니다. 예를 들어, ['posts', { userId: 1 }]와 같이 설정해 특정 사용자에 대한 데이터를 캐싱할 수 있습니다.
DevTools:리액트 쿼리 개발자 도구를 사용하여 쿼리 상태, 캐시된 데이터, refetch 상태 등을 시각적으로 확인할 수 있습니다. 이는 디버깅과 최적화에 매우 유용합니다.
◼ React Query 라이프 사이클
먼저 useQuery()가 실행되는 컴포넌트가 마운트되면 useQuery()를 통해 쿼리 함수가 실행되고 데이터를 받아옵니다. 받아 온 데이터는 useQuery()에서 지정해 줬던 쿼리 키를 이용해 캐싱, 즉 캐시에 저장이 되는데요. 이렇게 캐시에 저장된 데이터는 fresh 상태에서 staleTime이 지나면 stale 상태로 변경됩니다. 유저가 데이터를 요청하게 되면 캐시된 데이터를 먼저 보여주게 되는데, 이때 데이터가 fresh 상태면 추가적인 refetch를 진행하지 않고, stale 상태면 백그라운드에서(자체적으로 알아서) refetch를 진행합니다. refetch가 끝나면 새로운 데이터로 유저에게 보여주고요. 컴포넌트가 언마운트되어서 데이터가 inactive 상태가 되면 gcTime(가비지 컬렉션 타임) 동안 캐시에 저장되어 있다가 그 이후에 가비지 콜렉터에 의해 삭제가 되면서 이 여정은 마무리 됩니다.
◼ 요약
캐시는 자주 사용하는 데이터를 미리 저장해 두어, 백엔드에서 데이터를 매번 받아오는 대신 빠르게 접근할 수 있게 해주는 임시 저장소입니다. 웹 브라우저와 리액트 쿼리 같은 라이브러리에서도 캐시를 사용해 성능을 향상시키고 네트워크 비용을 절감합니다. 또한 스스로 캐쉬 관리를 하여 최신데이터를 받오올수 있도록 공간확보 또한 가능합니다.
'[노트장] 적으며 정리해 보는 이론 > React Query' 카테고리의 다른 글
[React Query] useMutation (0) | 2024.06.19 |
---|---|
[React Query] invalidateQueries (0) | 2024.06.19 |
[React Query] IsError, IsPending, retry (0) | 2024.06.19 |