1. React Query란?

우동이·2022년 4월 21일
1

React-Query

목록 보기
1/3
post-thumbnail

1. React-Query란?

  • 서버와 API를 통신하면서 가져오는 값들에 대해 Update / Caching / Error-Handling 등 비동기 통신 과정에서 다양한 처리를 진행할 수 있습니다.
  • 기본적으로 서버 상태를 관리해주는 라이브러리입니다.
    • 컴포넌트는 렌더링만 집중할 수 있도록 도와줍니다.
  • 지원 기능
    • Caching 기능 제공
      • 일반적으로 5분 후에 가비지 컬렉터가 수거합니다!
      • chacheTime으로 조절 가능
    • Get을 통해 불러온 데이터가 Update 되었을 때 자동 갱신 ( Get을 다시 요청 )
    • 오래된 데이터 최신화 ( Get 다시 요청 )
    • 중복 Get 요청을 한번만 요청 ( 옵션으로 조정 가능 )
    • 무한 스크롤 지원
    • React Hook과 비슷하여 사용 편리
    • 친절한 공식문서
  • React Query에서 관리하는 기본적인 Data의 상태 ( 중요 )
종류설명
fetching요청중인 Query
fresh만료되지 않는 최신의 데이터, 컴포넌트가 마운트 / 업데이트가 발생해도 데이터를 다시 재요청 하지 않음
stale만료된 과거의 데이터, 일정 시간이 지나면 가비지 컬렉터가 수거
inactive사용하지 않는 Query로 일정 시간이 지나면 가비지 컬렉터가 캐시에서 제거
delete가비지 컬렉터가 캐시에서 제거한 Query
  • React Query의 기본 default 설정
    • useQuery로 가져온 데이터는 기본적으로 stale 상태
    • stale 상태의 Query들은 아래의 4가지 경우 백그라운드에서 refetching( 서버로 부터 재요청 ) 실행
      • 새로운 쿼리 인스턴스가 마운트
      • 브라우저 윈도우가 다시 포커스
      • 네트워크 재연결
      • refetchInterval 옵션 활성화
    • 모든 Query의 Data는 캐싱이 이루어짐
      • 해당 Date는 inactive상태가 되고 일반적으로 5분 후에 가비지 컬렉터가 수거
    • 백그라운드에서 3번 쿼리 요청 실패시 에러 처리
    • Query의 결과로 만들어진 stale한 데이터는 업데이트 전까지 보전
      • Query 결과는 데이터가 변경되지 않은 경우 참조가 변경되지 않고 유지

2. 설치 및 셋팅

yarn add react-query 
  • index.js
import React from "react";
import App from "./App";
import { createRoot } from "react-dom/client";
import { QueryClient, QueryClientProvider } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";

const container = document.getElementById("root");
const root = createRoot(container);
const queryClient = new QueryClient();

root.render(
  <QueryClientProvider client={queryClient}>
    {/* devtools */}
    <ReactQueryDevtools initialIsOpen={true} />
    <App />
  </QueryClientProvider>
);

3. useQuery

  • 서버로부터 데이터를 Get 하기 위한 API 입니다.
  • 파라미터
    • 첫번째: unique Key ( 다른 컴포넌트에서도 해당 키로 동일한 호출 가능 )
      • String
      • Array: [ unique Key, value ]
        • 쿼리가 변수에 의존하는 경우에는 QueryKey 에도 해당 변수를 추가해주어야한다.
        • value 값은 useQuery 함수 내부의 파라미터로 값이 전달 됩니다.
          • useQuery(['key', id], () => axios.get(http://.../${id}));
    • 두번째: API 호출하는 비동기 함수 ( Promise )
    • 세번째: options
  • Return
    • api의 로딩중 / 성공 / 실패 여부
      • status: 3가지의 상태를 표시
    • api의 return value 값을 포함한 객체
    • 실패시 error 객체
  • 비동기로 작동
    • 컴포넌트 한개에 여러개의 useQuery가 존재할 경우 동시에 실행됩니다.
      • useQuery를 다중으로 사용할 경우 useQueries 사용
      • 동기로 작동하기 위해서는 enabled 사용
  • 소스코드
    • 기본적으로 다른 컴포넌트에서도 Key가 동일할 경우 1번만 요청하며 그 다음부터는 캐싱된 데이터를 불러옵니다.
    • 브라우저 탭을 변경하거나 해당 화면 포커싱이 될 때마다 새로운 Get 요청을 통해 데이터를 다시 불러옵니다.
      • refetchOnWindowFocus 옵션으로 설정 가능
    • 또한 Get 요청이 실패할 경우 지속적으로 몇번 호출하다가 나중에 isError = true 값으로 바뀌면서 error 객체를 리턴합니다.
      • retry 옵션으로 설정 가능
import React from "react";
import axios from "axios";
import { useQuery } from "react-query";

import "./App.css";

function App() {
  const fetchList = () => {
    return axios(`https://jsonplaceholder.typicode.com/posts/1`);
  };

  const { status, isLoading, isSuccess, isError, data, error } = useQuery(
    "key",
    fetchList
  );

  return <div>Hello World</div>;
}

export default App;
  • 데이터 로딩의 활용
import React from "react";
import axios from "axios";
import { useQuery } from "react-query";

import "./App.css";

function App() {
  const fetchList = () => {
    return axios(`https://jsonplaceholder.typicode.com/posts/1`);
  };

  const { status, isLoading, isSuccess, isError, data, error } = useQuery(
    "key",
    fetchList
  );

  console.log(status);

  if (isLoading) {
    return <span>Loading</span>;
  }

  if (isError) {
    return <span>{error.message}</span>;
  }

  return <div>{data.data.title}</div>;
}

export default App;

4. Options ( 더 자세한건 공식문서 참조 )

  • refetchOnWindowFocus: boolean
    • 데이터가 stale 상태일 때 윈도우가 포커싱 될 때마다 refetch를 실행합니다. ( 기본값: true )
      • 예시) 크롬에서 다른 탭을 눌렀다가 다시 원래의 탭을 돌아온 경우
      • stale: 최신이 아닌 데이터, React Query는 캐시되 데이터를 stale하다고 정의
      • refetch: 서버로 부터 데이터를 불러오는 과정
    • refetchOnWindowFocus: always: 항상 윈도우 포커싱 될 때 refetch 진행
  • retry: number / boolean
    • 실패한 쿼리에 대한 재시도를 설정하는 옵션
    • 기본적으로 3번 재시도
    • true일 경우 무한 재시도 / false일 경우 재시도를 하지 않습니다.
  • enabled: boolean
    • React Query가 자동으로 실행되지 않게 설정하는 옵션입니다.
      • 원래 해당 페이지가 렌더링 되면서 useQuery()가 존재할 경우 자동으로 서버로 데이터 요청
    • true일 경우 요청하지 않고 / false일 경우 요청합니다.
    • 보통 특정 변수를 활용해서 그 변수의 값이 들어올 경우 요청하도록 설정할 때 사용
import React, { useState } from "react";
import axios from "axios";
import { useQuery } from "react-query";

import "./App.css";

function App() {
  const fetchList = () => {
    return axios(`https://jsonplaceholder.typicode.com/posts/1`);
  };

  const [id, setId] = useState("");

  // 2초 뒤 ID값이 들어옴으로 아래의 useQuery 실행
  setTimeout(() => {
    setId(3);
  }, 2000);

  // 포커싱이 변경되도 호출 x / 에러 발생히 재호출 0번
  const { status, isLoading, isSuccess, isError, data, error } = useQuery(
    ["key", id],
    fetchList,
    {
      enabled: !!id,
      refetchOnWindowFocus: false,
      retry: 0,
    }
  );

  console.log(status);

  if (isLoading) {
    return <span>Loading</span>;
  }

  if (isError) {
    return <span>{error.message}</span>;
  }

  return <div>{data && data.data.title}</div>;
}

export default App;
  • staleTime: number / Infinity
    • 데이터의 fresh 상태를 유지하는 시간으로 해당 시간이 지나면 stale 상태가 됩니다. ( 기본적으로 0 )
      • fresh: 최신 상태의 데이터
        • fresh 상태일 때는 쿼리가 다시 mount되어도 fetch가 실행되지 않음
      • stale: 최신 상태가 아닌 데이터
  • cacheTime: number / Infinity
    • inactive 상태인 캐시 데이터가 메모리에 남아있는 시간입니다. ( 기본 5분으로 설정 )
      • inactive: 사용하지 않는 쿼리, 일정 시간이 지나면 가비지 컬렉터가 캐시에서 제거
    • 해당 시간이 지나면 가비지 컬렉터에 의해 메모리에서 제거됩니다.
  • refetchOnMount: booelan / always
    • 데이터가 stale 상태일 경우 마운트 될 때마다 refaetch를 실행하는 옵션입니다. ( 기본적으로 true )
    • always 설정시 마운트 할 때마다 retetch
  • refetchOnReconnect: boolean / always
    • 데이터가 stale 상태일 경우 네트워크 연결이 다시 이루어질 때 retetch를 실행하는 옵션입니다. ( 기본적으로 true )
    • always 설정시 계속 재 연결될 때 retetch 실행
  • onSuccess: (data) => void
    • Query가 성공할 때 실행되는 함수입니다.
    • 파라미터로 data를 받을 수 있으며 성공할 때 서버에서 넘어오는 Response 입니다.
  • onError: (error) => void
    • Query가 실패할 때 실행되는 함수입니다.
    • 파라미터로 error를 받을 수 있으며 서버에서 요청이 실패할 때 받을 수 있는 Response 입니다.
  • onSettled: (data, error) => void
    • onSuccessonError를 혼용으로 사용할 수 있는 옵션이며 API 요청의 성공 / 실패에 따라 자동으로 파라미터가 전달되는 함수 입니다.
  • initialData: data / () => data
    • Query가 아직 생성되지 않거나 캐시되지 않았을 때 Query 캐시 데이터의 초기 데이터를 설정할 수 있습니다.
    • staleTime이 설정되지 않았다면 초기 데이터도 기본적으로 stale 상태로 취급

5. 참고

profile
아직 나는 취해있을 수 없다...

0개의 댓글