React-Query란?

JooSehyun·2024년 12월 19일
0

[Study]

목록 보기
50/56
post-thumbnail

React-Query / TanStack Query

TanStack Query 문서

TanStack Query는 서버 상태를 관리하고 비동기 데이터 페칭을 간편하게 할 수 있도록 도와주는 라이브러리다. React Query로 시작했지만, 이제는 React뿐만 아니라 다른 프레임워크에서도 사용할 수 있도록 확장되었다.


설치

npm install @tanstack/react-query


기능 특징

  1. 자동 캐싱 및 동기화 : 데이터를 자동으로 캐싱하고, 필요할 때 자동으로 동기화한다.

  2. 백그라운드 데이터 업데이트: 백그라운드에서 데이터를 자동으로 업데이트하여 최신 상태를 유지한다.

  3. 쿼리 무효화 및 재페칭: 특정 조건이 충족되면 쿼리를 무효화하고 재페칭할 수 있다.

  4. 폴링 및 실시간 데이터: 주기적으로 데이터를 페칭하거나 실시간 데이터를 처리할 수 있다.

  5. 오프라인 지원: 오프라인 상태에서도 데이터를 관리할 수 있다.

  6. 개별 쿼리 관리: 각 쿼리를 독립적으로 관리할 수 있다.


기본 사용법

import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query';

const queryClient = new QueryClient();

// App.jsx 또는 main.jsx
function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <MyComponent />
    </QueryClientProvider>
  );
}

App.jsx 또는 main.jsx 최상위 컴포넌트에 QueryClientProvide 로 감싼다.


// MyComponent
function MyComponent() {
  const { isLoading, error, data } = useQuery(['todos'], fetchTodos);

  if (isLoading) return 'Loading...';
  if (error) return 'An error has occurred: ' + error.message;

  return (
    <div>
      {data.map(todo => (
        <p key={todo.id}>{todo.title}</p>
      ))}
    </div>
  );
}

//fetchTodos
async function fetchTodos() {
  const response = await fetch('/api/todos');
  return response.json();
}

fetchTodos 라는 서버에서 데이터를 가져오는 함수를 만들고 사용하는 컴포넌트에서 const { isLoading, error, data } = useQuery(['todos'], fetchTodos); 를 사용한다.


useQuery 훅

const { data, isLoading, error } = useQuery(
    ['posts', userId],
    () => fetchPosts(userId), 
    { enabled: !!userId } 
  );

React QueryuseQuery 훅은 쿼리의 상태를 관리하는 여러 유용한 값들을 반환한다. 각 값은 현재 쿼리의 상태를 나타내거나 조작하는 데 사용된다.


기본 반환값과 설명

  1. data
  • 역할 : 쿼리가 성공적으로 데이터를 가져왔을 때 반환되는 값이다.
  • 값의 종류 :
    1. 쿼리함수(queryFn)가 반환한 데이터
    2. 초기 데이터(initialData 옵션)를 제공한 경우 초기값으로 설정
  • 초기 상태 : undefined
  • 사용 예시 :
    const { data } = useQuery('posts', fetchPosts);
	console.log(data); // 서버에서 가져온 데이터

  1. isLoading
  • 역할 : 쿼리가 처음 실행될 때 로딩 상태를 나타낸다.
  • 값의 종류 :
    1. true : 쿼리가 데이터를 가져오는 중.
    2. false : 데이터 가져오기가 완료되었거나 실패한 경우
  • 초기 상태 : true
  • 사용 예시 :
    const { isLoading } = useQuery('posts', fetchPosts);
	if (isLoading) return <div>Loading...</div>;

  1. error
  • 역할 : 쿼리 함수가 실패했을 때 반환되는 에러 객체
  • 값의 종류 :
    1. null : 에러가 발생하지 않은 경우
    2. Error 객체 : 쿼리가 실패한 경우 발생한 에러
  • 초기 상태 : null
  • 사용 예시 :
    const { error } = useQuery('posts', fetchPosts);
	if (error) return <div>Error: {error.message}</div>;

  1. isError
  • 역할 : 쿼리의 상태가 에러인지 여부를 나타낸다.
  • 값의 종류 :
    1. true : 쿼리가 실패했음
    2. false : 에러가 발생하지 않음
  • 초기 상태 : false
  • 사용 예시 :
	const { isError } = useQuery('posts', fetchPosts);
	if (isError) return <div>Something went wrong!</div>;

  1. isFetching
  • 역할 : 쿼리가 현재 데이터를 가져오는 중인지 여부를 나타낸다.
  • 값의 종류 :
    1. true : 데이터를 가져오는 중
    2. false : 데이터를 가져오기가 완료되었거나 대기 상태
  • 차이점 : isLoading과 달리 쿼리가 초기 로딩 상태가 아닌 경우에도 데이터를 리패칭할 때 true가 된다.
  • 사용 예시 :
	const { isFetching } = useQuery('posts', fetchPosts);
	if (isFetching) return <div>Fetching latest data...</div>;

  1. status
  • 역할 : 쿼리의 상태를 나타내는 문자열
  • 값의 종류 :
    1. "idel" : 쿼리가 아직 실행되지 않음
    2. "loading : 데이터를 가져오는 중
    3. "success" : 데이터 가져오기 성공
    4. "error" : 데이터 가져오기 실패
  • 사용 예시 :
	const { status } = useQuery('posts', fetchPosts);
	if (status === 'loading') return <div>Loading...</div>;
	if (status === 'error') return <div>Error occurred!</div>;

  1. refetch
  • 역할 : 데이터를 다시 가져오는 함수
  • 사용 예시 :
	const { refetch } = useQuery('posts', fetchPosts);

    const handleRefresh = () => {
      refetch();
    };

	return <button onClick={handleRefresh}>Refresh Data</button>;

요약

반환값설명초기 상태
data쿼리 함수가 반환한 데이터undefined
isLoading데이터 가져오는 중인지 여부true
error실패 시 발생한 에러 객체null
isError에러 발생 여부false
isFetching데이터 가져오는 중인지 여부false
status쿼리의 상태 (idle, loading, 등)"idle"
refetch데이터를 다시 가져오는 함수-

useQuery 매개변수

  1. 첫 번째 인자 : queryKey (유니크한 키)
- 데이터 쿼리를 식별하기 위한 고유한 키이다.
- 타입 : string | unknown[]
- 역할 :
	- React Query는 이 키를 기반으로 데이터를 캐싱하고 중복 요청을 방지한다.
    - 배열 형태로 구체화된 키를 사용할 수 있으며, 배열의 요소는 동적으로 변경 가능하다.
- 예시 : 
    const { data } = useQuery(['posts', userId], fetchPosts);
	// 'posts'는 데이터의 이름이고, userId는 특정 데이터를 식별하는 동적 요소입니다.

  1. 두 번째 인자 : queryFn (데이터를 가져오는 함수)
- 서버에서 데이터를 가져오는 함수이다.
- 타입 : (context: QueryFunctionContext) => Promise<TData>
- 역할 :
	- 데이터를 비동기로 가져오며, React Query가 이 함수의 반환값을 캐싱한다.
    - 함수 내부에서 queryKey를 사용할 수 있다.
- 예시 :
	const fetchPosts = async (context) => {
  		const [_, userId] = context.queryKey; // queryKey로부터 userId 추출
  		const response = await fetch(`https://api.example.com/posts/${userId}`);
  		if (!response.ok) throw new Error('Failed to fetch posts');
  		return response.json();
	};

	const { data } = useQuery(['posts', userId], fetchPosts);

  1. 세 번째 인자 : options (선택 사항)

    • 쿼리의 동작을 제어하는 옵션 객체이다.
    • 타입 : UseQueryOptions<TData, TError, TQueryFnData>
    • 주요 옵션 :
      - enabled :
      - boolean 값으로 쿼리 실행 여부를 제어한다.
      - 기본값은 true이며, false로 설정하면 쿼리가 자동으로 실행되지 않는다.
      - 동적 매개변수(userId)가 유효할 때만 실행하도록 설정할 때 유용하다.
    • 예시 :
    const { data } = useQuery(
    	['posts', userId],
    	() => fetchPosts(userId),
    	{ enabled: !!userId } // userId가 유효할 때만 쿼리를 실행
    );

0개의 댓글