[React-Query] 개념 정리
본문 바로가기
🧱 언어 모음집/React Query

[React-Query] 개념 정리

by 은돌1113 2022. 6. 15.
728x90
 

react-query 개념 및 정리

react-query 개념 및 정리, react, react16, hook, useState, useRef, useMemo, useEffect, useReducer, useCallback, useQuery 동기적으로 실행

kyounghwan01.github.io

 

[React.js] React Query

Next.js 에 React Query 를 도입하며, 관련된 사용법과 옵션을 기록하기 위한 글입니다. 💁 React Query의 장점 ✅ 서버 데이터 캐싱 ✅ 데이터 패칭 시 로딩, 에러 처리를 한 곳에서 처리 가능 ✅ prefetchin

velog.io


react-query란?

: 서버의 값을 클라이언트에 가져오거나, 캐싱, 값 업데이트, 에러 핸들링 등 비동기 과정을 더욱 편리하게 할 수 있습니다.


사용하는 이유는?

서버와 클라이언트의 데이터를 분리하기 위해 사용한다고 한다.


장점은?

주로 아래와 같이 프론트 개발자가 구현하기 귀찮은 일들을 대신 수행해준다.
✅ 서버 데이터 캐싱
✅ 데이터 패칭 시 로딩, 에러 처리를 한 곳에서 처리 가능
✅ prefetching, retry 등 다양한 옵션
✅ 쉬운 상태 관리

React Query의 라이프 사이클

 

라이프 사이클(Life Cycle) 별 상태 개념

fetching : 데이터 요청 상태
fresh : 데이터가 프레시한 (만료되지 않는 상태)
stale : 데이터가 만료된 상태
- 한번 프런트로 내려준 서버 데이터는 최신화가 필요한 데이터라고 볼 수 있다.
- 그 사이에 다른 유저가 데이터를 추가, 수정, 삭제할 수 있기 때문에
- 컴포넌트가 마운트, 업데이트되면 데이터를 다시 요청한다.
- fresh에서 stale로 넘어가는 시간의 기본값은 0이다.
inactive : 사용하지 않는 상태
- 일정 시간이 지나면 가비지 컬렉터(Garbage Collection, 쓰레기 수집)가 캐시에서 제거한다.
- 기본값은 5분이다.
(기본값을 무한대(infinite)로 설정하면 데이터 누수가 너무 많아지고, 오류가 발생할 수 있어하지 말라고 했다.)
delete : 가비지 컬렉터(Garbage Collection, 쓰레기 수집)에 의해 캐시에서 제거된 상태

라이프 사이클(Life Cycle)

(🐣 : 내 나름대로 이해한 내용으로 풀어봄 | 틀린 정보일 수 있음)

(인스턴스 : 실행 중인 프로세스 / 즉, 실행 중인 요청?)

1) A 쿼리 인스턴스가 mount 됨
  🐣 사용자에게 컴포넌트가 보일 때 A 쿼리 인스턴스를 서버에 요청함

2) 네트워크에서 데이터를 fetch 하고 A라는 query key로 캐싱함
  🐣 서버에서 데이터를 가져온 후 해당 데이터를 브라우저에 캐싱함

3) 이 데이터는 fresh 상태에서 staleTime (기본값 0) 이후 stale 상태로 변경됨
  🐣 캐싱된 데이터는 만료되지 않는 상태에서 staleTime 이후 만료된 상태로 변경됨

4) A 쿼리 인스턴스가 unmount 됨
  🐣 A 쿼리 인스턴스가 컴포넌트에서 사라짐

5) 캐시는 cacheTime(기본값 5분)만큼 유지되다가 가비지 컬렉터(Gerbage Collection)로 수집됨
  🐣 브라우저에 저장된 캐시는 cacheTime이 지난 후 가비지 컬렉터에 수집되어 삭제됨

6) 만일 cacheTime이 지나기 전에 A 쿼리 인스턴스가 새롭게 mount 되면, fetch가 실행되고, fresh 한 값을 가져오는 동안 캐시 데이터를 보여줌
  🐣 만약 cacheTime이 지나기 전에 A 쿼리 인스턴스가 새롭게 요청되면, 데이터를 요청하고, 데이터를 새로 가져오기            전까지는 이미 브라우저에 캐시 된 데이터를 보여줌

StaleTime이란?

데이터가 fresh 👉 stale 상태로 변경되는 데 걸리는 시간 즉, 데이터 요청 후 만료되기 까지 걸리는 시간
fresh 상태일 때는 쿼리 인스턴스가 새롭게 mount 되어도, 네트워크 fetch가 일어나지 않는다.
  🐣 데이터가 만료 되기 전에 쿼리를 새롭게 실행시킬 경우에는 새로운 요청을 하지 않는다.

cacheTime이란?

데이터가 inactive 상태일 때, 캐싱된 상태로 남아있는 시간
  🐣 데이터를 사용하지 않은 상태

쿼리 인스턴스가 unmount 되면, 데이터는 inactive 상태로 변경된다.
  🐣 쿼리 요청 후 쿼리 요청 작업이 끝나면 데이터는 사용하지 않은 상태로 변경된다.

캐시는 cacheTime만큼 유지된다.
  🐣 기본값 5분, 캐싱된 데이터는 5분 동안 유지된다.

cacheTime이 지나면 가비지 콜렉터(Garbage Collection)에 수집된다.
  🐣 데이터가 사용된 상태가 되면 삭제된다.

cacheTime이 지나기 전에 쿼리 인스턴스가 다시 마운트 되면, 데이터를 fetch 하는 동안 캐시 데이터를 보여준다.
  🐣 캐싱된 데이터가 사라지기 전에 쿼리를 새롭게 요청하면, 데이터를 불러오는 동안 이미 저장된 데이터를 보여준다.

useQuery

데이터 fetching에 쓰이는 Hook, GET 메소드 사용 시에 자주 사용된다.

QueryKey

QueryKey를 기반으로 데이터 캐싱을 관리한다.
- 문자열 또는 배열로 저장할 수 있다.
// 문자열
useQuery('todos', ...)
// 배열
useQuery(['todos'], ...)
쿼리가 변수에 의존하는 경우에는 QueryKey에도 해당 변수를 추가해줘야 한다.
const { data, isLoading, error } = useQuery(['todos', id], () => axios.get(`http://.../${id}`));

Query Functions

useQuery의 두 번째 인자에는 promise를 반환하는 함수를 넣어 줘야 한다.
// 방법 1
useQuery('todos', fetchTodos);

// 방법 2
useQuery(['todos', todoId], () => fetchTodoById(todoId));

Query Options

enable
- false 시 자동으로 데이터를 불러오는 것을 방지한다.
- default : true (자동으로 데이터를 불러옴)
ex) 클릭 이벤트 시에만, 데이터를 fetch 해야 할 경우 enable false로 설정해야 함

retry
- false : 데이터 fetch 실패 시 재요청하지 않는다.
- true : 데이터 fetch 실패 시 무한으로 재요청한다.
- number : 데이터 fetch 실패 시 number번만큼 재요청한다.

staleTime : 캐시가 fresh 하다고 인정하는 시간 (캐시가 사용되지 않았다고 인정하는 시간)
- number : 몇 {number} ms 후 stale 상태로 처리할지 설정 (기본값 : 0)
- Infinity : 데이터를 영원히 fresh 한 상태로 취급 *영원히 만료되지 않은 상태로 취급, 😨잘 모르면 안 쓰는 게 좋음)

cacheTime : 메모리에 살아있는 시간
- number : 몇 {number} ms 동안 캐시 데이터가 메모리에 남아있게 된다. 그 이후에는 가비지 컬렉터(Garbage Collection)에 의해서 삭제된다. 
- Infinity : 데이터를 영원히 fresh 한 상태로 취급 (영원히 사용하지 않은 상태로 취급, 😨잘 모르면 안 쓰는 게 좋음)

onSuccess : (data : TDdata) ⇒ void
- 데이터 fetch 성공 시 실행되는 콜백
- 매개변수로 받는 data에 요청받은 데이터가 들어온다.

onError : (error : TError) ⇒ void
- 데이터가 fetch 실패 시 실행되는 콜백
- 매개변수로 받는 error에 실패 정보가 들어온다.

onSettled : (data? TData, error?: TError) ⇒ void
- 데이터 fetch 성공, 실패와 관계없이 무조건 동작하는 콜백

select : (data : TData) ⇒ unknown
- 데이터를 가공할 때 사용하는 함수
- 이 함수에서 return 한 형태가 응답받은 데이터의 형태가 된다.

keepPreviousData
- 새로 fetch 한 데이터를 화면에 나타내기 전까지 기존에 있던 데이터를 계속 화면에 유지하는지에 대한 여부 결정

initalData
- 캐시 된 데이터가 없을 때, 표시할 초기값
- 브라우저 로컬 스토리지에 저장해둔 값으로 데이터를 초기화할 때 사용할 수 있다.

그 외 return 값

status
- idle : 초기 상태
- loading : 데이터 fetching 중일 때의 상태
- success : 데이터 fetch에 성공한 상태
- error : 데이터 fetch에 실패한 상태

isFetcing
- 데이터가 fetch 상태일 때 true, 캐싱 데이터가 있어서 백그라운드에서 fetch 되더라도 true

isLoading
- 캐싱된 데이터가 없을 때 또는 fetch 중인 경우 true

data
- 응답받은 데이터

error
- 실패 정보

refetch
- 수동으로 데이터 refetch를 실행하는 함수
- scale이나 cache 같은 설정들이 무시되고, 무조건 다시 데이터를 fetching 한다.

useMuation

서버 데이터를 업데이트할 때 쓰이는 Hook으로써, 데이터 생성/수정/삭제 시 자주 사용된다.

다음과 같이 post, put 등을 사용하여 데이터에 변경이 일어났을 때 사용된다.

const mutation = useMutation(newTodo => axios.post('/todos', newTodo))

const handleSubmit = useCallback(
  (newTodo) => {
    mutation.mutate(newTodo)
  },
  [mutation],
)

https://velog.io/@aeong98/React.js-React-Query


mutateAsync로 서버 response 가져오는 방법

const postTodo = (todo) => { 
  axios.post('/api/data', { todo }) 
}
const createTodo = useMutation(postTodo); 

createTodo.mutateAsync(todo).then((data) => {
   console.log(data);
   // console로 찍은 data가 서버의 response 값입니다.
});

useInfiniteQuery

: 가장 신선했던 기능 중 하나이다.

useInfiniteQuery란 파라미터 값만 변경하여, 동일한 useQuery를 무한정 호출할 때 사용된다.

보통 무한 스크롤(Infinite Scroll을 구현할 때 많이 사용된다고 한다.)

const {
   fetchNextPage,
   fetchPreviousPage,
   hasNextPage,
   hasPreviousPage,
   isFetchingNextPage,
   isFetchingPreviousPage,
   ...result
 } = useInfiniteQuery(queryKey, ({ pageParam = 1 }) => fetchPage(pageParam), {
   ...options,
   getNextPageParam: (lastPage, allPages) => lastPage.nextCursor,
   getPreviousPageParam: (firstPage, allPages) => firstPage.prevCursor,
 })
pageParam
- page를 지정한다. 기본값을 1로 설정한 상태에서 다음 데이터를 불러온다.

getNextPageParam (getPreviousPageParam)
- page를 1씩 증가시킨다.

예시 코드는 https://velog.io/@aeong98/React.js-React-Query 여기에서 볼 수 있다.


결론

🐣 boilerplate란?
: 변경 없이 계속하여 재사용하는 저작품을 말한다. 즉, 재사용 가능한 프로그램을 가리킨다.

 

https://velog.io/@aeong98/React.js-React-Query

728x90

댓글