Jul 11, 2024
Setup
npm install @tanstack/react-query
npm install @tanstack/react-query-devtools
Basic Configuration
QueryClient
and QueryClientProvider
to wrap your main app component
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<YourMainComponent />
</QueryClientProvider>
);
}
useQuery
hook
import { useQuery } from '@tanstack/react-query';
const fetchPosts = async () => {
const response = await fetch('/api/posts');
return response.json();
};
function Posts() {
const { data, error, isLoading } = useQuery(['posts'], fetchPosts);
if (isLoading) return 'Loading...';
if (error) return 'Error!';
return (
<div>
{data.map(post => (
<div key={post.id}>{post.title}</div>
))}
</div>
);
}
data
, error
, isLoading
, status
, etc.useMutation
hook
import { useMutation, useQueryClient } from '@tanstack/react-query';
const createPost = async (newPost) => {
const response = await fetch('/api/posts', {
method: 'POST',
body: JSON.stringify(newPost),
});
return response.json();
};
function CreatePost() {
const queryClient = useQueryClient();
const mutation = useMutation(createPost, {
onSuccess: () => {
queryClient.invalidateQueries(['posts']);
}
});
return (
<button onClick={() => mutation.mutate({ title: 'New Post' })}>
Create Post
</button>
);
}
data
, error
, isLoading
, mutate
, mutateAsync
, etc.['posts', postId]
)invalidateQueries
to update cache after mutations
queryClient.invalidateQueries(['posts', postId])
isLoading
to show loading stateisError
and error
objectimport { ReactQueryDevtools } from '@tanstack/react-query-devtools';
<ReactQueryDevtools initialIsOpen={false} />
const fetchPosts = async ({ pageParam = 1 }) => {
const response = await fetch(`/api/posts?page=${pageParam}`);
return response.json();
};
const { data, isLoading, fetchNextPage } = usePaginatedQuery('posts', fetchPosts);
useInfiniteQuery
for loading more data
import { useInfiniteQuery } from '@tanstack/react-query';
const fetchPosts = ({ pageParam = 1 }) => fetch(`/api/posts?page=${pageParam}`).then(res => res.json());
const { data, fetchNextPage, hasNextPage } = useInfiniteQuery('posts', fetchPosts, {
getNextPageParam: lastPage => lastPage.nextPage ?? false
});
queryClient.prefetchQuery(['post', id], () => fetchPost(id));
useQuery('posts', fetchPosts, {
placeholderData: [{ id: 0, title: 'Loading...' }],
});
Interested? Check out Kyle's full React course for a deeper dive.