#
기본
- 데이터 가져오기 및 저장
- useQuery 를 사용
고유 키
를 사용하여 응답 데이터를 자동 캐싱
검색하고 관리
하는 데 사용#
쿼리 키
- 첫 번째 요소가 문자열 (쿼리의 고유 식별자를 나타냄)
- 후속 요소는 가져오는 특정 데이터를 정의하는 매개 변수인 배열 (optional)
import { useQuery } from '@tanstack/react-query';
// 사용자 정보를 가져오는 API 호출 함수
const fetchUser = async (userId) => {
const response = await fetch(`https://example.com/api/users/${userId}`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
};
function UserProfile({ userId }) {
// useQuery에서 쿼리 키로 ['user', userId]를 사용합니다.
const { data, error, isLoading } = useQuery(['user', userId], () => fetchUser(userId));
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
// 데이터 로딩 완료 후 사용자 프로필 렌더링
return (
<div>
<h1>{data.name}</h1>
<p>Email: {data.email}</p>
</div>
);
}
#
부실 데이터 및 백그라운드 업데이트
- "staleTime" 옵션을 통해 쿼리 데이터가 얼마나 오랫동안 "신선"하게 유지될지를 설정
- 해당 데이터가 부실해질 때, 컴포넌트가 다시 포커스를 얻거나 새로운 쿼리가 발생할 때 자동으로 백그라운드에서 데이터를 업데이트
function UserProfile({ userId }) {
const { data, isLoading } = useQuery(['user', userId], () => fetchUserProfile(userId), {
staleTime: 1000 * 60 * 5, // 5분 동안 데이터를 신선하게 유지
});
if (isLoading) return <div>Loading...</div>;
return <div>{data.name}</div>;
}
#
캐시 시간 제한
- "cacheTime" 비활성화된 쿼리 데이터가 캐시에 얼마나 오래 남아있을지 설정
- 가비지 컬렉션을 통해 캐시에서 자동으로 제거
- 메모리 사용량을 관리하는 데 유용
function UserProfile({ userId }) {
const { data, isLoading } = useQuery(['user', userId], () => fetchUserProfile(userId), {
staleTime: 1000 * 60 * 5, // 데이터를 5분 동안 신선하게 유지
cacheTime: 1000 * 60 * 60 * 24, // 데이터를 24시간 동안 캐시에 유지
});
if (isLoading) return <div>Loading...</div>;
return <div>{data.name}</div>;
}
📢 Q. Cache time 과 Stale time 에 대해
- stale time 에 지정한 기간 동안은 신선한 Data 로 간주
- 새로운 요청이 발생해도 기존의 쿼리키를 통해 캐싱한 데이터를 사용
- 지정한 기능이 지나면 "부실"한 데이터로 간주하여 해당 쿼리가 호출될 때 자동으로 데이터를 재패치
- stale time 이 지났을 때
- 해당 데이터를 사용하는 컴포넌트가 포함된 페이지로 돌아올 때
- => 시간이 지났다고 무조건 재패치가 아니라 위와 같은 조건을 만족해야 함
- cache time 은 비활성화된 쿼리 데이터가 캐시에 남아 있을 시간을 정의
- 쿼리가 비활성 상태가 되어 cacheTime 동안 사용되지 않으면, 이후에는 캐시에서 해당 데이터를 자동으로 삭제
- 이는 캐시 메모리 관리에 유용
- 비활성화된 상태
- cache time 이 지나는 동안 사용하지 않는 경우
#
낙관적 업데이트
- "useMutation" 훅과 함께 onMutate, onSuccess, onError, onSettled 콜백을 사용
- 데이터를 업데이트하고, 필요한 경우 롤백
import { useMutation, useQueryClient } from '@tanstack/react-query';
function ProfileUpdateForm({ userId }) {
const queryClient = useQueryClient();
const { mutate } = useMutation(updateUserProfile, {
onMutate: async (newData) => {
// 취소를 위한 현재 캐시된 데이터 백업
const previousUserData = queryClient.getQueryData(['user', userId]);
// 낙관적 업데이트: UI를 즉시 업데이트
queryClient.setQueryData(['user', userId], oldData => ({
...oldData,
...newData,
}));
return { previousUserData };
},
onError: (err, newData, context) => {
// 에러 발생 시 롤백
queryClient.setQueryData(['user', userId], context.previousUserData);
},
onSettled: () => {
// 성공 또는 에러 후 캐시된 데이터를 다시 가져옴
queryClient.invalidateQueries(['user', userId]);
},
});
// 예를 들어 사용자 프로필 업데이트 로직
const handleSubmit = (newData) => {
mutate({ userId, newData });
};
캐시를 사용하는 경우
- 초기 데이터 로딩
- 처음으로 데이터를 마운트하고 요청할 때, 캐시 확인 후 없으면 데이터 요청
- 동시 요청
- 여러 컴포넌트가 동일한 데이터를 필요로 할 때 매우 유용
- "동일한 쿼리 키" (['user', userId]) 를 사용하는 다른 요청이 동시에 발생하면, 이 요청들을 대기 상태로 전환
- 동일한 캐시된 데이터를 사용하여 렌더링되며, 이 과정에서 단 하나의 네트워크 요청만 발생
- 백그라운드 데이터 새로 고침
- 부실한 데이터의 경우, 업데이트된 데이터를 가져오는 동안 현재 데이터를 즉시 제공
- 데이터 프리패치
- 곧 필요할 수 있는 데이터를 프리페치하여 요청 시 즉시 액세스할 수 있도록 캐시에 저장
- 캐시 조작
- 개발자는 필요에 따라 다시 가져오기를 트리거하거나 UI를 업데이트
📢 캐싱 메커니즘은 서버 상태를 효율적으로 관리하여 데이터 가져오기를 최적화하고 네트워크 요청을 줄이며 원활한 사용자 경험을 제공하도록 설계