PromleeBlog
sitemapaboutMe

posting thumbnail
React(TanStack) Query 사용법 기초 (React Native, Expo)
React(TanStack) Query Guide for React Native (Expo)

📅

🚀

들어가기 전에🔗

React Native로 앱을 만들다 보면 외부 API에서 데이터를 가져오거나 서버에 데이터를 저장하는 일이 자주 발생합니다. 이때 단순히 fetch 함수만 사용하면, 로딩 상태나 오류 처리, 캐싱 등 여러 번 반복되는 패턴을 매번 직접 구현해야 해서 번거롭습니다.
이를 해결하기 위해
TanStack Query
를 사용하면 데이터 패칭을 매우 간편하고 안정적으로 처리할 수 있습니다. 이 글에서는 React Native (Expo) 환경에서 TanStack Query를 설치하고 활용하는 방법을 기초부터 차근차근 예제와 함께 안내해 드리겠습니다.

🚀

TanStack Query란 무엇인가요?🔗

TanStack Query는 서버에서 가져오는 데이터를 효율적으로 관리할 수 있도록 도와주는 상태 관리 라이브러리입니다. 예전 이름은 React Query였으며, 현재는 다양한 플랫폼을 지원하는 범용 도구로 발전했습니다.
React Native에서도 다음과 같은 상황에서 유용하게 사용할 수 있습니다:

🚀

설치 및 Expo 환경 설정🔗

React Native (Expo) 프로젝트에서 TanStack Query를 사용하려면 다음과 같이 설치합니다:
npx expo install @tanstack/react-query
npm i -D @tanstack/eslint-plugin-query

🚀

QueryClientProvider 설정하기🔗

설치를 마쳤다면 QueryClient를 만들고, 앱의 최상단 컴포넌트를 QueryClientProvider로 감싸야 합니다.
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      {/* 앱 컴포넌트들 */}
    </QueryClientProvider>
  );
}
이렇게 설정하면 이제부터 앱 전체에서 TanStack Query 기능을 사용할 수 있게 됩니다.

🚀

기본적인 useQuery 사용법🔗

이제 가장 기본적인 사용법부터 살펴보겠습니다. JSONPlaceholder의 사용자 API(/users)를 가져와서 리스트로 표시해보겠습니다.
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
import { FlatList, Text, View } from 'react-native';
 
const fetchUsers = async () => { // 정보를 fetch하는 함수
  const res = await axios.get('https://jsonplaceholder.typicode.com/users');
  return res.data;
};
 
export default function UserList() {
  const { data, isLoading, isError, error } = useQuery({
    queryKey: ['users'], // 쿼리의 고유 식별자
    queryFn: fetchUsers, // 정보를 fetch하는 함수
  });
 
  if (isLoading) return <Text>불러오는 중...</Text>;
 
  if (isError) return <Text>오류 발생: {(error as Error).message}</Text>;
 
    return (
    <FlatList
      data={data}
      keyExtractor={(item) => item.id.toString()}
      renderItem={({ item }) => <Text>{item.name}</Text>}
    />
  );
}

🚀

쿼리 키(queryKey)의 중요성🔗

queryKey는 요청을 구분하고 캐시를 적용하는 데 매우 중요한 역할을 합니다. 배열 형태로 작성하며, 특정 파라미터에 따라 다르게 구성할 수 있습니다.
useQuery({
  queryKey: ['user', userId],
  queryFn: () => fetchUser(userId),
});
여기서 userId가 다르면 다른 쿼리로 인식되어 각기 다른 캐시를 사용하게 됩니다.

🚀

앱 포커스 상태에 따른 refetch🔗

앱이 포커스를 얻을 때 자동으로 쿼리를 다시 실행하고 싶다면 AppStatefocusManager를 사용합니다:
import { useEffect } from 'react';
import { AppState, Platform } from 'react-native';
import { focusManager } from '@tanstack/react-query';
function onAppStateChange(status) {
  if (Platform.OS !== 'web') {
    focusManager.setFocused(status === 'active');
  }
}
useEffect(() => {
  const subscription = AppState.addEventListener('change', onAppStateChange);
  return () => subscription.remove();
}, []);

🚀

React Navigation과 화면 포커스 시 refetch🔗

React Navigation에서는 useFocusEffect를 활용하여 화면에 들어올 때 데이터를 갱신할 수 있습니다:
import { useFocusEffect } from '@react-navigation/native';
import { useCallback } from 'react';
 
export function useRefreshOnFocus(refetch) {
  useFocusEffect(
    useCallback(() => {
      refetch();
    }, [])
  );
}

🚀

useMutation 사용 예시🔗

서버에 데이터를 등록하거나 수정할 때는 useMutation을 사용합니다. 아래는 게시글을 추가하는 예시입니다:
import { useMutation, useQueryClient } from '@tanstack/react-query';
import axios from 'axios';
 
const createPost = async (newPost) => {
  const res = await axios.post('https://jsonplaceholder.typicode.com/posts', newPost);
  return res.data;
};
 
export function NewPostButton() {
  const queryClient = useQueryClient(); // 쿼리 클라이언트 인스턴스
  const mutation = useMutation({
    mutationFn: createPost, // 뮤테이션 함수
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['posts'] }); // 쿼리 데이터 무효화
    },
  });
  return (
    <Button
      title="새 글 작성"
      onPress={() => mutation.mutate({ title: '제목', body: '내용' })} // 뮤테이션 실행
    />
  );
}

🚀

React Native에서 Devtools 사용🔗

웹과는 달리 React Native에서는 Devtools를 바로 사용할 수는 없습니다. 다음과 같은 도구를 통해 쿼리 상태를 확인할 수 있습니다:

Expo 플러그인🔗

다음 명령어로 플러그인을 설치합니다.
npx expo install @dev-plugins/react-query
플러그인을 사용하려면 다음과 같이 설정해야 합니다.
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { useReactQueryDevTools } from '@dev-plugins/react-query';
 
const queryClient = new QueryClient({});
 
export default function App() {
  useReactQueryDevTools(queryClient); // 디버깅 도구 초기화
 
  return (
    <QueryClientProvider client={queryClient}>
      {/* ... */}
    </QueryClientProvider>
  );
}
이제 앱을 실행한 터미널에서 shift + M 키를 눌러 Open @dev-plugins/react-query 를 선택하면 웹 브라우저에서 디버깅 도구를 열 수 있습니다.

🚀

결론🔗

React Native (Expo)에서 TanStack Query를 사용하면 데이터 패칭, 캐싱, 에러 처리, 상태 관리 등을 매우 간단하고 효율적으로 구현할 수 있습니다. 특히 모바일 환경에서는 네트워크 연결 상태나 앱 포커스에 따라 데이터 동기화를 자동으로 처리하는 기능이 매우 유용합니다.
이번 포스팅을 통해 기초부터 실전 사용까지 예제와 함께 익히셨기를 바랍니다.

참고🔗