📚

React Query Overview

Jul 11, 2024

React Query Overview

Introduction

  • Presenter: Kyle from Web Dev Simplified
  • Purpose: Introduction and deep dive into TanStack Query (React Query)
  • Promises to show the utility of React Query in simplifying asynchronous state management, specifically for API requests

What is React Query?

  • Asynchronous State Management Library
    • Manages state from API requests
    • Handles caching, pre-fetching, and data synchronization
  • Benefits
    • Simplifies the process of fetching data
    • Automates retries, data syncing, and error handling

Getting Started

  1. Setup

    • Create a React Application (e.g., using Vite)
    • Install React Query and Dev Tools npm install @tanstack/react-query npm install @tanstack/react-query-devtools
  2. Basic Configuration

    • Include 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> ); }

Core Concepts

Queries

  • Fetching data (e.g., list of posts)
  • Use 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> ); }
  • Important Properties: data, error, isLoading, status, etc.

Mutations

  • Changing data (e.g., creating a new post)
  • Use 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> ); }
  • Important Properties: data, error, isLoading, mutate, mutateAsync, etc.

Query Keys and Caching

  • Key Uniqueness: Compound keys for unique identifiers (e.g., ['posts', postId])
  • Cache Management: Use invalidateQueries to update cache after mutations queryClient.invalidateQueries(['posts', postId])

Handling Query States

  • Loading: Use isLoading to show loading state
  • Error: Handle errors with isError and error object
  • Success: Automatically managed, no special handling usually required

Dev Tools

  • Visualize queries and mutations import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; <ReactQueryDevtools initialIsOpen={false} />

Advanced Features

Paginated and Infinite Queries

  • Pagination: Managing page number in query keys const fetchPosts = async ({ pageParam = 1 }) => { const response = await fetch(`/api/posts?page=${pageParam}`); return response.json(); }; const { data, isLoading, fetchNextPage } = usePaginatedQuery('posts', fetchPosts);
  • Infinite Scroll: Using 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 });

Prefetching

  • Prefetch Query: Preloading data before navigation queryClient.prefetchQuery(['post', id], () => fetchPost(id));

Placeholder and Initial Data

  • Placeholder Data: Temporary display data while loading
  • Initial Data: Assumed valid for caching useQuery('posts', fetchPosts, { placeholderData: [{ id: 0, title: 'Loading...' }], });

Conclusion

  • React Query greatly simplifies asynchronous state management
  • Flexibility: From simple data fetching to complex state management tasks
  • Optimization: With caching, prefetching, pagination, and more

Interested? Check out Kyle's full React course for a deeper dive.