useQuery({
queryKey: ['posts', username],
queryFn: () => getPostsByUsername(username),
staleTime: 60 * 1000,
});
useQuery()가 있는 컴포넌트가 마운트되면 useQuery()의 쿼리 함수인 queryFn()이 자동으로 실행되면서 데이터를 가져온다.
queryKey를 이용해 받아온 데이터를 캐싱할 수 있다. 이때 특정 데이터만 따로 캐싱하도록 queryKey 배열에 값을 추가할 수도 있다.
queryFn으로는 백엔드에서부터 데이터를 받아오는 함수를 지정하면 된다.
staleTime 옵션을 활용해 데이터가 언제까지 fresh 상태를 유지할 것인지 정할 수 있다.
const {
data: postsData,
isPending,
isError,
} = useQuery({
queryKey: postsQueryKey,
queryFn: postsQueryFn,
});
if (isPending) return '로딩 중입니다...';
if (isError) return '에러가 발생했습니다.';
useQuery()의 리턴 값을 활용해서 로딩과 에러 화면 처리를 간편하게 할 수 있다.
const uploadPostMutation = useMutation({
mutationFn: (newPost) => uploadPost(newPost),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['posts'] });
},
});
const handleUploadPost = (newPost) => {
uploadPostMutation.mutate(newPost, {
onSuccess: () => {
toast('포스트가 성공적으로 업로드 되었습니다!');
},
});
};
데이터베이스에 값을 추가하거나 변경하는 경우 useMutation()을 활용하면 된다.
알아서 쿼리 함수를 실행하는 useQuery()와는 달리 mutate() 함수를 실행해야 mutationFn이 실행된다.
useMutation()과 mutate() 함수의 onSuccess, onError, onSettled 등의 옵션을 통해 각 상황에 맞는 다양한 처리를 해 줄 수 있다.
특히 onSuccess에서 query invalidation을 통해 자동으로 refetch가 되도록 할 수 있는데, 이렇게 하면 새로고침을 하지 않아도 새로운 데이터가 화면에 바로 보인다.