React-Query는 서버 상태 관리 라이브러리로, React 애플리케이션에서 데이터 페칭, 캐싱, 동기화, 업데이트를 쉽게 관리할 수 있게 도와줌. 서버와의 데이터 통신을 다루기 위한 API 호출을 효율적으로 관리하고, 자동 리프레시, 로딩 상태 관리, 오류 처리와 같은 기능을 제공하여 서버와 클라이언트 사이의 데이터를 쉽게 동기화할 수 있음.
일반적인 React 애플리케이션에서는 useEffect, useState를 사용해 API 호출과 데이터를 관리하지만, 이 방식은 다음과 같은 어려움이 있음
React-Query는 이러한 문제를 해결하여 데이터 페칭을 더욱 간편하게 관리할 수 있음. 주요 기능으로는 자동 캐싱, 배경 리페칭, 데이터 무효화, 쿼리 중복 제거 등을 제공함.
React-Query를 시작하려면 라이브러리를 설치하고 QueryClient와 QueryClientProvider를 설정해야 함.
npm install react-query
yarn add react-query
이제 QueryClient 인스턴스를 생성하고, 이를 QueryClientProvider로 애플리케이션의 최상위 컴포넌트에 제공하여 React-Query를 설정함.
// App.js
import React from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';
import UserList from './UserList';
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<UserList />
</QueryClientProvider>
);
}
export default App;
useQuery는 서버에서 데이터를 가져오는 데 사용하는 React-Query의 주요 훅임. useQuery는 캐시된 데이터를 자동으로 관리해주며, 로딩 상태, 오류 상태를 자동으로 처리할 수 있음.
import React from 'react';
import { useQuery } from 'react-query';
async function fetchUsers() {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
}
function UserList() {
const { data, error, isLoading } = useQuery('users', fetchUsers);
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<ul>
{data.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
export default UserList;
useQuery는 자동으로 로딩 상태와 에러 상태를 관리하며, 데이터를 가져오면 data 속성에 저장함.
useQuery는 다양한 옵션을 통해 데이터 페칭을 유연하게 관리할 수 있음.
const { data, error, isLoading } = useQuery('users', fetchUsers, {
staleTime: 5000, // 데이터가 '오래되기 전'까지의 시간
cacheTime: 10000, // 캐시에 유지되는 시간
refetchOnWindowFocus: false, // 브라우저 포커싱 시 리페칭 비활성화
});
Mutation은 데이터를 변경하는 API 호출(예: POST, PUT, DELETE) 등을 처리하기 위한 훅임. useMutation을 사용하여 데이터 업데이트나 삭제 작업을 관리할 수 있음.
import React from 'react';
import { useMutation, useQueryClient } from 'react-query';
async function addUser(newUser) {
const response = await fetch('https://jsonplaceholder.typicode.com/users', {
method: 'POST',
body: JSON.stringify(newUser),
headers: {
'Content-Type': 'application/json',
},
});
return response.json();
}
function AddUser() {
const queryClient = useQueryClient();
const mutation = useMutation(addUser, {
onSuccess: () => {
// 성공 시 'users' 쿼리를 무효화하여 다시 로드
queryClient.invalidateQueries('users');
},
});
const handleAddUser = () => {
mutation.mutate({ name: 'New User', email: 'newuser@example.com' });
};
return (
<div>
<button onClick={handleAddUser}>Add User</button>
{mutation.isLoading && <p>Adding user...</p>}
{mutation.isError && <p>Error adding user</p>}
</div>
);
}
export default AddUser;
특정 이벤트 이후 데이터를 다시 가져와야 할 때 invalidateQueries를 사용하여 해당 쿼리를 무효화함.
queryClient.invalidateQueries('users');
React-Query는 데이터가 오래된 상태가 되면 자동으로 백그라운드에서 리페칭하여 최신 데이터를 유지함. staleTime 옵션을 통해 리페칭 주기를 조정할 수 있음.
useQuery('users', fetchUsers, {
staleTime: 60000, // 1분 동안 데이터가 신선하게 유지됨
});
React-Query는 React Query Devtools를 제공해 쿼리의 상태와 캐시 정보를 시각적으로 확인할 수 있음.
npm install @tanstack/react-query-devtools
설치 후 ReactQueryDevtools 컴포넌트를 애플리케이션에 추가하면 사용 가능함.
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
function App() {
return (
<QueryClientProvider client={queryClient}>
<UserList />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
);
}