React Query

젠젠·2022년 3월 24일
1

react

목록 보기
2/2
post-thumbnail

상태관리 관련 라이브러리들을 탐색하던 중 React Query라는 것을 알게 되었고, React Query에 관한 우테크세미나 영상을 찾아서 세미나 내용을 정리해보았다.
우아한테크 React Query 세미나 영상 링크

React Query의 필요성

Frontend에서 필요한 상태관리는 redux, recoil 등의 상태관리 라이브러리를 사용하여 관리하고 있다.

보편적인 Redux Store 사용 형태

리덕스로 구현된 비동기통신 중 fetch한 값을 저장하는 코드들이 꽤 있다.

Store ⇒ ‘전역 상태가 저장되고 관리되는 공간’ 인데,

상태관리 영역이 서버 값을 저장하는데까지 확장이 돼버렸다. 이게 괜찮을까?

모두 Store로 관리하면,

  • API 통신 관련 코드가 모두 Store에 있다.
  • 반복되는 isFetching, isError 등의 API 관련 상태들
  • 반복되는 비슷한 구조의 API 통신 코드

서버에서 받아야 하는 Server State 특성

  • Client에서 제어하거나 소유되지 않은 원격의 공간에서 관리되고 유지됨.
  • Fetching이나 Updating에 비동기 API가 필요함.
  • 다른사람들과 공유되는 것으로 사용자가 모르는 사이에 변경될 수 있음.
  • 신경쓰지 않는다면 잠재적으로 “out of date”가 될 가능성을 지님.

⇒ 사실상 FE에서 이 값들이 저장돼있는 state들은 일종의 캐시이다.

Client State와 Server State를 모두 Redux store로 관리하는게 좋을까?

React Query란?

React Query

  • Server State와 관련된 데이터가져오기, 캐싱, 동기화, 데이터 업데이트를 해준다.
  • zero-config로 즉시 사용가능하고, 원하면 config도 커스텀 가능하다.

React Query의 3가지 Core 개념

Queries

보통 GET으로 받아올 대부분의 API에 사용하는 아이(데이터 fetching용)

import { useQuery } from 'react-query';

function App() {

// 'todos'가 Query Key
// fetchTodoList가 Query Function
// 원한다면 세번째 인자로 config option 설정 가능하다.
const info = useQuery('todos', fetchTodoList);

}
  • React Query는 Query Key에 따라 query caching을 관리한다.
  • Query Key는 String, Array 형태로 사용가능하다.
  • Query Function : Promise를 반환하는 함수이다. 데이터를 resolve하거나 error를 throw한다.

useQuery 반환 값들

  • data: 마지막으로 성공한 resolved된 데이터(Response)
  • error: 에러가 발생했을 때 반환되는 객체
  • isFetching: Request가 in-flight 중일 때 true
  • status, isLoading, isSuccess, isLoading 등 : 모두 현재 query의 상태
  • refetch : 해당 query refetch 하는 함수 제공
  • remove : 해당 query cache에서 지우는 함수 제공
  • etc.

useQuery Options

  • onSuccess, onError, onSettled : query fetching 성공/실패/완료 시 실행 할 Side Effect 정의
  • enabled : 자동으로 query를 실행시킬지 말지 여부
  • retry : query 동작 실패 시, 자동으로 retry 할지 결정하는 옵션
  • select : 성공 시 가져온 data를 가공해서 전달 (예: data.data.result 등의 구조일 때 가공작업)
  • keepPreviousData : 새롭게 fetching 시 이전 데이터 유지 여부
  • refetchInterval : 주기적으로 refetch 할 지 결정 하는 옵션
  • etc.

추천하는 파일구조

  • Query 선언부를 파일로 관리

여러개 쓸 땐?

여러 개의 useQuery를 쓰면 알아서 병렬적으로 잘 동작한다.

Mutations

데이터 Updating 시 사용하는 아이(CRUD 중 Create/Update/Delete에 모두 사용함)

// Promise반환함수만 넣어주면 된다.
// (디버깅 원할 땐 Query Key를 넣어주면 devtools에서 볼 수 있다)
const mutation = useMutation(newTodo => {
	return axios.post('/todos', newTodo);
});

useMutation 반환 값들

  • mutate : mutation을 실행하는 함수
  • mutateAsync : mutate와 비슷하지만 Promise를 반환한다.
  • reset : mutation 내부 상태 clean
  • 나머지들은 useQuery랑 비슷함

useMutation Options

  • onMutate : 본격적인 Mutation 동작 전에 먼저 동작하는 함수로, Optimistic update 적용할 때 유용 (Optimistic update : 결과를 낙관적으로 보고 미리 상태 등 변경하고 실패하면 롤백하는 방법)
  • 나머진 useQuery랑 비슷함

Query Invalidation

  • 간단히 queryClient를 통해 invalidate 메소드를 호출하면 된다.
    // Invalidate every query in the cache
    queryClient.invalidateQueries();
    
    // Invalidate every qeury with a key that starts with 'todos'
    queryClient.invalidateQueries('todos');
    • 이렇게 작성하면 해당 Key를 가진 query 는 stale 취급되고, 현재 rendering 되고 있는 query들은 백그라운드에서 refetch된다.

Caching과 Synchronization은?

  • cacheTime : 메모리에 얼만큼 있을 것인지(해당 시간 이후 GC에 의해 처리, default는 5분)
  • staleTime : 얼마의 시간이 흐른 후에 데이터를 stale 취급할 것인지(default는 0)
  • refetchOnMount / refetchOnWindowFocus / refetchOnReconnect ⇒ true 이면 Mount / Window Focus / Reconnect 시점에 data가 stale이라고 판단되면 모두 refetch(모두 default는 true)

어디에서 값들을 관리할까?

QueryClient 내부적으로 Context를 사용한다.

React Query 장점

  • 서버상태 관리에 용이하며(Redux, MobX 사용할 때보다) 직관적인 API 호출 코드
  • API 처리에 관한 각종 인터페이스 및 옵션 제공
  • Client Store가 FE에서 정말 필요한 전역상태만 남아 Store답게 사용됨
  • devtools 제공으로 원활한 디버깅
  • Cache 전략 필요할 때 좋음

고민이 필요한 부분

  • Component가 상대적으로 비대해짐 (Component 설계/분리에 대한 고민 필요)
  • 좀 더 난이도가 높아진 프로젝트 설계(Component 유착 최소화 및 사용처 파악 필요)
  • React Query의 장점을 더 잘 활용할 방법(단순히 API 통신 이상의 가능성)
profile
4년차 프론트엔드 개발자입니다.

0개의 댓글