### React Query Quick Start Example Source: https://tanstack.com/query/v4/docs/framework/react/quick-start.md Illustrates setting up React Query with QueryClientProvider, using useQuery for data fetching, and useMutation for data updates with query invalidation. Ensure you have the necessary API functions (getTodos, postTodo) defined. ```tsx import { useQuery, useMutation, useQueryClient, QueryClient, QueryClientProvider, } from '@tanstack/react-query' import { getTodos, postTodo } from '../my-api' // Create a client const queryClient = new QueryClient() function App() { return ( // Provide the client to your App ) } function Todos() { // Access the client const queryClient = useQueryClient() // Queries const query = useQuery({ queryKey: ['todos'], queryFn: getTodos }) // Mutations const mutation = useMutation({ mutationFn: postTodo, onSuccess: () => { // Invalidate and refetch queryClient.invalidateQueries({ queryKey: ['todos'] }) }, }) return (
) } render(, document.getElementById('root')) ``` -------------------------------- ### Install @tanstack/query-async-storage-persister Source: https://tanstack.com/query/v4/docs/framework/react/plugins/createAsyncStoragePersister.md Install the necessary packages for async storage persistence. This includes the persister itself and the react-query-persist-client. ```bash npm install @tanstack/query-async-storage-persister @tanstack/react-query-persist-client ``` ```bash pnpm add @tanstack/query-async-storage-persister @tanstack/react-query-persist-client ``` ```bash yarn add @tanstack/query-async-storage-persister @tanstack/react-query-persist-client ``` -------------------------------- ### Install @tanstack/react-query-persist-client Source: https://tanstack.com/query/v4/docs/framework/react/plugins/createSyncStoragePersister.md Install the necessary packages for persistence functionality. ```bash npm install @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client ``` ```bash pnpm add @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client ``` ```bash yarn add @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client ``` -------------------------------- ### Basic useInfiniteQuery Setup Source: https://tanstack.com/query/v4/docs/framework/react/reference/useInfiniteQuery.md Demonstrates the basic setup for useInfiniteQuery, including essential options like queryKey, queryFn, and how to define getNextPageParam and getPreviousPageParam. ```tsx const { fetchNextPage, fetchPreviousPage, hasNextPage, hasPreviousPage, isFetchingNextPage, isFetchingPreviousPage, ...result } = useInfiniteQuery({ queryKey, queryFn: ({ pageParam = 1 }) => fetchPage(pageParam), ...options, getNextPageParam: (lastPage, allPages) => lastPage.nextCursor, getPreviousPageParam: (firstPage, allPages) => firstPage.prevCursor, }) ``` -------------------------------- ### React Application Setup with TanStack Query Source: https://tanstack.com/query/v4/docs/framework/react/examples/simple This snippet shows the basic structure of a React application using Vite and integrating TanStack Query and its devtools. Ensure you have React, ReactDOM, and TanStack Query packages installed. ```jsx import React from 'react'; import ReactDOM from 'react-dom/client'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import App from './App'; const queryClient = new QueryClient(); ReactDOM.createRoot(document.getElementById('root')).render( ); ``` -------------------------------- ### Simple React Query Example Source: https://tanstack.com/query/v4/docs/framework/react/examples/simple This snippet demonstrates a basic setup for TanStack Query in a React application. It fetches data from the GitHub API and displays repository information. Ensure you have React, ReactDOM, TanStack Query, TanStack Query Devtools, and Axios installed. ```jsx /* eslint-disable jsx-a11y/anchor-is-valid */ import React from 'react' import ReactDOM from 'react-dom/client' import { QueryClient, QueryClientProvider, useQuery, } from '@tanstack/react-query' import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import axios from 'axios' const queryClient = new QueryClient() export default function App() { return ( ) } function Example() { const { isLoading, error, data, isFetching } = useQuery({ queryKey: ['repoData'], queryFn: () => axios .get('https://api.github.com/repos/tannerlinsley/react-query') .then((res) => res.data), }) if (isLoading) return 'Loading...' if (error) return 'An error has occurred: ' + error.message return (

{data.name}

{data.description}

👀 {data.subscribers_count}{' '} ✨ {data.stargazers_count}{' '} 🍴 {data.forks_count}
{isFetching ? 'Updating...' : ''}
) } const rootElement = document.getElementById('root') ReactDOM.createRoot(rootElement).render() ``` -------------------------------- ### Install React Query Devtools Source: https://tanstack.com/query/v4/docs/framework/react/devtools.md Install the devtools package using npm, pnpm, or yarn. Ensure the major version matches your React Query installation. ```bash npm i @tanstack/react-query-devtools@4 ``` ```bash pnpm add @tanstack/react-query-devtools@4 ``` ```bash yarn add @tanstack/react-query-devtools@4 ``` -------------------------------- ### Install React Query with NPM Source: https://tanstack.com/query/v4/docs/framework/react/installation.md Use this command to install React Query v4 via NPM. ```bash npm i @tanstack/react-query@4 ``` -------------------------------- ### App Component Setup Source: https://tanstack.com/query/v4/docs/framework/react/examples/star-wars Sets up the main App component with QueryClientProvider, BrowserRouter, and ThemeProvider. Includes React Query Devtools for debugging. ```jsx import React from 'react' import { BrowserRouter as Router } from 'react-router-dom' import { ThemeProvider } from '@material-ui/core' import { createMuiTheme } from '@material-ui/core/styles' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import './styles.css' import Layout from './Layout' const queryClient = new QueryClient() export default function App() { return ( ) } const theme = createMuiTheme({ typography: { h1: { fontFamily: 'Roboto Mono, monospace', }, h2: { fontFamily: 'Roboto Mono, monospace', }, h3: { fontFamily: 'Roboto Mono, monospace', }, h4: { fontFamily: 'Roboto Mono, monospace', }, h5: { fontFamily: 'Roboto Mono, monospace', }, h6: { fontFamily: 'Roboto Mono, monospace', }, }, }) ``` -------------------------------- ### Install React Query with Yarn Source: https://tanstack.com/query/v4/docs/framework/react/installation.md Use this command to install React Query v4 via Yarn. ```bash yarn add @tanstack/react-query@4 ``` -------------------------------- ### Install React Query with pnpm Source: https://tanstack.com/query/v4/docs/framework/react/installation.md Use this command to install React Query v4 via pnpm. ```bash pnpm add @tanstack/react-query@4 ``` -------------------------------- ### Custom SSR Setup with Suspense Source: https://tanstack.com/query/v4/docs/framework/react/guides/ssr.md Implement custom server-side rendering by traversing the component tree with `ssrPrepass` to fetch Suspense data. This example shows how to handle requests, render to string, dehydrate state, and send HTML with embedded state. ```tsx import { dehydrate, QueryClient, QueryClientProvider, } from '@tanstack/react-query' import ssrPrepass from 'react-ssr-prepass' async function handleRequest(req, res) { const queryClient = new QueryClient() // React SSR does not support ErrorBoundary try { // Traverse the tree and fetch all Suspense data (thrown promises) await ssrPrepass() } catch (e) { console.error(e) // Send the index.html (without SSR) on error, so user can try to recover and see something return res.sendFile('path/to/dist/index.html') } const html = ReactDOM.renderToString( , ) const dehydratedState = dehydrate(queryClient) res.send( `
${html}
`) queryClient.clear() } ``` -------------------------------- ### Install Testing Libraries Source: https://tanstack.com/query/v4/docs/framework/react/guides/testing.md Install necessary libraries for testing custom React Query hooks. For React 18+, use @testing-library/react directly. ```sh npm install @testing-library/react-hooks react-test-renderer --save-dev ``` -------------------------------- ### React Query Playground Setup Source: https://tanstack.com/query/v4/docs/framework/react/examples/playground Sets up the QueryClient, QueryClientProvider, and interactive controls for adjusting query options like staleTime and cacheTime. Includes initial data and global configuration for queries. ```jsx import React from 'react' import ReactDOM from 'react-dom/client' import { QueryClient, QueryClientProvider, useQuery, useQueryClient, useMutation, } from '@tanstack/react-query' import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import './styles.css' let id = 0 let list = [ 'apple', 'banana', 'pineapple', 'grapefruit', 'dragonfruit', 'grapes', ].map((d) => ({ id: id++, name: d, notes: 'These are some notes' })) let errorRate = 0.05 let queryTimeMin = 1000 let queryTimeMax = 2000 const queryClient = new QueryClient() function Root() { const [staleTime, setStaleTime] = React.useState(1000) const [cacheTime, setCacheTime] = React.useState(3000) const [localErrorRate, setErrorRate] = React.useState(errorRate) const [localFetchTimeMin, setLocalFetchTimeMin] = React.useState(queryTimeMin) const [localFetchTimeMax, setLocalFetchTimeMax] = React.useState(queryTimeMax) React.useEffect(() => { errorRate = localErrorRate queryTimeMin = localFetchTimeMin queryTimeMax = localFetchTimeMax }, [localErrorRate, localFetchTimeMax, localFetchTimeMin]) React.useEffect(() => { queryClient.setDefaultOptions({ queries: { staleTime, cacheTime, }, }) }, [cacheTime, staleTime]) return (

The "staleTime" and "cacheTime" durations have been altered in this example to show how query stale-ness and query caching work on a granular level

Stale Time:{' '} setStaleTime(parseFloat(e.target.value, 10))} style={{ width: '100px' }} />
Cache Time:{' '} setCacheTime(parseFloat(e.target.value, 10))} style={{ width: '100px' }} />

Error Rate:{' '} setErrorRate(parseFloat(e.target.value, 10))} style={{ width: '100px' }} />
Fetch Time Min:{' '} setLocalFetchTimeMin(parseFloat(e.target.value, 10))} style={{ width: '60px' }} />{' '}
Fetch Time Max:{' '} setLocalFetchTimeMax(parseFloat(e.target.value, 10))} style={{ width: '60px' }} />


) } function App() { const queryClient = useQueryClient() const [editingIndex, setEditingIndex] = React.useState(null) const [views, setViews] = React.useState(['', 'fruit', 'grape']) // const [views, setViews] = React.useState([""]) ``` -------------------------------- ### Fetch API Example for Infinite Queries Source: https://tanstack.com/query/v4/docs/framework/react/guides/infinite-queries.md Demonstrates the API response structure for paginated data, including the data array and the cursor for the next page. ```bash fetch('/api/projects?cursor=0') // { data: [...], nextCursor: 3} fetch('/api/projects?cursor=3') // { data: [...], nextCursor: 6} fetch('/api/projects?cursor=6') // { data: [...], nextCursor: 9} fetch('/api/projects?cursor=9') // { data: [...] } ``` -------------------------------- ### Basic Mutation Example Source: https://tanstack.com/query/v4/docs/framework/react/guides/mutations.md This example demonstrates how to use the `useMutation` hook to add a new todo. It shows how to handle loading, error, and success states, and how to trigger the mutation with variables. ```tsx function App() { const mutation = useMutation({ mutationFn: (newTodo) => { return axios.post('/todos', newTodo) }, }) return (
{mutation.isLoading ? ( 'Adding todo...' ) : ( <> {mutation.isError ? (
An error occurred: {mutation.error.message}
) : null} {mutation.isSuccess ?
Todo added!
: null} )}
) } ``` -------------------------------- ### Install ESLint Plugin Query Source: https://tanstack.com/query/v4/docs/eslint/eslint-plugin-query.md Install the ESLint plugin for TanStack Query using npm, pnpm, or yarn. ```bash npm i -D @tanstack/eslint-plugin-query@4 ``` ```bash pnpm add -D @tanstack/eslint-plugin-query@4 ``` ```bash yarn add -D @tanstack/eslint-plugin-query@4 ``` -------------------------------- ### Correct useQuery syntax with object Source: https://tanstack.com/query/v4/docs/eslint/prefer-query-object-syntax.md Example of the correct `useQuery` syntax using an options object. This is the preferred method for consistency and future compatibility. ```javascript import { useQuery } from '@tanstack/react-query'; useQuery({ queryKey, queryFn, onSuccess, }); ``` -------------------------------- ### Persist Query Client Usage Example Source: https://tanstack.com/query/v4/docs/framework/react/plugins/persistQueryClient.md Demonstrates basic usage of `persistQueryClient` with a `localStoragePersister`. Note that this approach does not handle component lifecycle for unsubscription. ```typescript // 🚨 never unsubscribes from syncing persistQueryClient({ queryClient, persister: localStoragePersister, }) // 🚨 happens at the same time as restoring ReactDOM.createRoot(rootElement).render() ``` -------------------------------- ### Setup Offline Persister and Query Client Source: https://tanstack.com/query/v4/docs/framework/react/examples/offline Initializes the persister using `localStorage` and configures the `QueryClient` with default options, cache callbacks for toast notifications, and default mutation functions for offline resilience. ```jsx import * as React from 'react' import { useQuery, QueryClient, MutationCache, onlineManager, useIsRestoring, } from '@tanstack/react-query' import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import toast, { Toaster } from 'react-hot-toast' import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client' import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister' import { Link, Outlet, ReactLocation, Router, useMatch, } from '@tanstack/react-location' import * as api from './api' import { movieKeys, useMovie } from './movies' const persister = createSyncStoragePersister({ storage: window.localStorage, }) const location = new ReactLocation() const queryClient = new QueryClient({ defaultOptions: { queries: { cacheTime: 1000 * 60 * 60 * 24, // 24 hours staleTime: 2000, retry: 0, }, }, // configure global cache callbacks to show toast notifications mutationCache: new MutationCache({ onSuccess: (data) => { toast.success(data.message) }, onError: (error) => { toast.error(error.message) }, }), }) // we need a default mutation function so that paused mutations can resume after a page reload queryClient.setMutationDefaults(movieKeys.all(), { mutationFn: async ({ id, comment }) => { // to avoid clashes with our optimistic update when an offline mutation continues await queryClient.cancelQueries({ queryKey: movieKeys.detail(id) }) return api.updateMovie(id, comment) }, }) export default function App() { return ( { // resume mutations after initial restore from localStorage was successful queryClient.resumePausedMutations().then(() => { queryClient.invalidateQueries() }) }} > ) } function Movies() { const isRestoring = useIsRestoring() return ( , }, { path: ':movieId', element: , errorElement: , loader: ({ params: { movieId } }) => queryClient.getQueryData(movieKeys.detail(movieId)) ?? // do not load if we are offline or hydrating because it returns a promise that is pending until we go online again // we just let the Detail component handle it (onlineManager.isOnline() && !isRestoring ? queryClient.fetchQuery({ queryKey: movieKeys.detail(movieId), queryFn: () => api.fetchMovie(movieId), }) : undefined), }, ]}> ) } function List() { const moviesQuery = useQuery({ queryKey: movieKeys.list(), queryFn: api.fetchMovies, }) if (moviesQuery.isLoading && moviesQuery.isFetching) { return 'Loading...' } ``` -------------------------------- ### React Native App Setup with TanStack Query Source: https://tanstack.com/query/v4/docs/framework/react/examples/react-native This snippet shows the root component setup for a React Native application using TanStack Query. It includes initializing the QueryClient, setting up the QueryClientProvider, and integrating navigation. It also demonstrates custom hooks for managing app state and online status to control query refetching. ```typescript import * as React from 'react' import { AppStateStatus, Platform } from 'react-native' import { NavigationContainer } from '@react-navigation/native' import { QueryClient, QueryClientProvider, focusManager, } from '@tanstack/react-query' import { useAppState } from '@app/hooks/useAppState' import { MoviesStack } from '@app/navigation/MoviesStack' import { useOnlineManager } from '@app/hooks/useOnlineManager' function onAppStateChange(status: AppStateStatus) { // React Query already supports in web browser refetch on window focus by default if (Platform.OS !== 'web') { focusManager.setFocused(status === 'active') } } const queryClient = new QueryClient({ defaultOptions: { queries: { retry: 2 } }, }) export default function App() { useOnlineManager() useAppState(onAppStateChange) return ( ) } ``` -------------------------------- ### React Query Playground Setup Source: https://tanstack.com/query/v4/docs/framework/react/examples/playground Sets up the QueryClient and configures default query options for staleTime and cacheTime. It also manages local state for error rate and fetch times, updating global variables accordingly. ```jsx import React from 'react' import ReactDOM from 'react-dom/client' import { QueryClient, QueryClientProvider, useQuery, useQueryClient, useMutation, } from '@tanstack/react-query' import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import './styles.css' let id = 0 let list = [ 'apple', 'banana', 'pineapple', 'grapefruit', 'dragonfruit', 'grapes', ].map((d) => ({ id: id++, name: d, notes: 'These are some notes' })) let errorRate = 0.05 let queryTimeMin = 1000 let queryTimeMax = 2000 const queryClient = new QueryClient() function Root() { const [staleTime, setStaleTime] = React.useState(1000) const [cacheTime, setCacheTime] = React.useState(3000) const [localErrorRate, setErrorRate] = React.useState(errorRate) const [localFetchTimeMin, setLocalFetchTimeMin] = React.useState(queryTimeMin) const [localFetchTimeMax, setLocalFetchTimeMax] = React.useState(queryTimeMax) React.useEffect(() => { errorRate = localErrorRate queryTimeMin = localFetchTimeMin queryTimeMax = localFetchTimeMax }, [localErrorRate, localFetchTimeMax, localFetchTimeMin]) React.useEffect(() => { queryClient.setDefaultOptions({ queries: { staleTime, cacheTime, }, }) }, [cacheTime, staleTime]) return ( <>
The "staleTime" and "cacheTime" durations have been altered in this example to show how query stale-ness and query caching work on a granular level
Stale Time:{' '} setStaleTime(parseFloat(e.target.value, 10))} style={{ width: '100px' }} /> Cache Time:{' '} setCacheTime(parseFloat(e.target.value, 10))} style={{ width: '100px' }} />
Error Rate:{' '} setErrorRate(parseFloat(e.target.value, 10))} style={{ width: '100px' }} /> Fetch Time Min:{' '} setLocalFetchTimeMin(parseFloat(e.target.value, 10))} style={{ width: '60px' }} />{' '} Fetch Time Max:{' '} setLocalFetchTimeMax(parseFloat(e.target.value, 10))} style={{ width: '60px' }} /> ) } function App() { const queryClient = useQueryClient() const [editingIndex, setEditingIndex] = React.useState(null) const [views, setViews] = React.useState(['', 'fruit', 'grape']) // const [views, setViews] = React.useState([""]); return (

This is a list of filters. You can add more filters to the list. Each filter will have its own query that is refetched when the filter changes.

    {views.map((view, index) => (
  • ))}

{editingIndex !== null ? ( <> ) : null}
) } function Todos({ initialFilter = '', setEditingIndex }) { const [filter, setFilter] = React.useState(initialFilter) const { status, data, isFetching, error, failureCount, refetch, } = useQuery({ queryKey: ['todos', { filter }], queryFn: fetchTodos, }) return (
Filter:{' '} setFilter(e.target.value)} /> {status === 'loading' ? ( 'Loading...' (Attempt: {failureCount + 1}) ) : status === 'error' ? ( ) : ( <> {data ? ( data.map((todo) => (
  • * {todo.name}{' '}
  • )) ) : null} {isFetching ? ( 'Background Refreshing...' (Attempt: {failureCount + 1}) ) : ( '' )} )}
    ) } function EditTodo({ editingIndex, setEditingIndex }) { const queryClient = useQueryClient() // Don't attempt to query until editingIndex is truthy const { status, data, isFetching, error, failureCount, refetch, } = useQuery({ queryKey: ['todo', { id: editingIndex }], queryFn: () => fetchTodoById({ id: editingIndex }), enabled: editingIndex !== null, }) const [todo, setTodo] = React.useState(data || {}) React.useEffect(() => { if (editingIndex !== null && data) { setTodo(data) } else { setTodo({}) } }, [data, editingIndex]) const saveMutation = useMutation({ mutationFn: patchTodo, onSuccess: (data) => { // Update `todos` and the individual todo queries when this mutation succeeds queryClient.invalidateQueries({ queryKey: ['todos'] }) queryClient.setQueryData(['todo', { id: editingIndex }], data) }, }) const onSave = () => { saveMutation.mutate(todo) } const disableEditSave = status === 'loading' || saveMutation.status === 'loading' return (
    {data ? ( <> Editing Todo "{data.name}" (# {editingIndex}) ) : null}
    setTodo({ ...todo, name: e.target.value })} disabled={disableEditSave} /> setTodo({ ...todo, notes: e.target.value })} disabled={disableEditSave} />
    ) } ReactDOM.createRoot(document.getElementById('root')).render( , ) ``` -------------------------------- ### Install ESLint Plugin Query with NPM Source: https://tanstack.com/query/v4/docs/framework/react/installation.md Install the ESLint plugin for React Query v4 using NPM. This helps catch bugs and inconsistencies during development. ```bash npm i -D @tanstack/eslint-plugin-query@4 ``` -------------------------------- ### Correct Query Key Dependency Source: https://tanstack.com/query/v4/docs/eslint/exhaustive-deps.md This example demonstrates the correct usage where `todoId` is included in both the `queryKey` and `queryFn`. This adheres to the exhaustive-deps rule, ensuring proper caching and refetching. ```tsx useQuery({ queryKey: ["todo", todoId], queryFn: () => api.getTodo(todoId) }) const todoQueries = { detail: (id) => ({ queryKey: ["todo", id], queryFn: () => api.getTodo(id) }) } ``` -------------------------------- ### Install ESLint Plugin Query with pnpm Source: https://tanstack.com/query/v4/docs/framework/react/installation.md Install the ESLint plugin for React Query v4 using pnpm. This helps catch bugs and inconsistencies during development. ```bash pnpm add -D @tanstack/eslint-plugin-query@4 ``` -------------------------------- ### Prefetching Data with `initialData` in Next.js Source: https://tanstack.com/query/v4/docs/framework/react/guides/ssr.md Use `getStaticProps` or `getServerSideProps` to fetch data on the server and pass it to `useQuery` via the `initialData` option. This is a quick setup for simple cases but has tradeoffs regarding data passing and timing. ```tsx export async function getStaticProps() { const posts = await getPosts() return { props: { posts } } } function Posts(props) { const { data } = useQuery({ queryKey: ['posts'], queryFn: getPosts, initialData: props.posts, }) // ... } ``` -------------------------------- ### React Router Integration Example Source: https://tanstack.com/query/v4/docs/framework/react/examples/react-router This component serves as a basic entry point for a React Router application integrated with React Query. It displays introductory text and links to relevant documentation. ```jsx import * as React from 'react' export default function Index() { return (

    This is a demo for integrating React Router with React Query.
    Check out{' '} the docs at reactrouter.com and{' '} the docs at tanstack.com .

    ) } ``` -------------------------------- ### PersistQueryClientProvider Setup Source: https://tanstack.com/query/v4/docs/framework/react/plugins/persistQueryClient.md Sets up the `PersistQueryClientProvider` for seamless cache persistence within a React application. This provider handles subscription, unsubscription, and prevents race conditions during cache restoration. ```typescript import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client' import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister' const queryClient = new QueryClient({ defaultOptions: { queries: { cacheTime: 1000 * 60 * 60 * 24, // 24 hours }, }, }) const persister = createSyncStoragePersister({ storage: window.localStorage, }) ReactDOM.createRoot(rootElement).render( , ) ``` -------------------------------- ### Next.js 13 App Directory: QueryClientProvider Setup Source: https://tanstack.com/query/v4/docs/framework/react/guides/ssr.md This client component sets up the QueryClientProvider, which is required for all React Query hooks to access the QueryClient context. It initializes a new QueryClient instance that persists across renders. ```tsx // app/providers.jsx 'use client' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' export default function Providers({ children }) { const [queryClient] = React.useState(() => new QueryClient()) return ( {children} ) } ``` -------------------------------- ### Basic GraphQL Request with TanStack Query Source: https://tanstack.com/query/v4/docs/framework/react/examples/basic-graphql-request This snippet illustrates a fundamental GraphQL query setup using TanStack Query. It requires the `graphql-request` library and a GraphQL endpoint. ```javascript import { useQuery } from '@tanstack/react-query'; import { request, gql } from 'graphql-request'; const endpoint = 'YOUR_GRAPHQL_ENDPOINT'; const query = gql` query GetTodos { todos { id title completed } } `; function useTodos() { return useQuery({ queryKey: ['todos'], queryFn: async () => { return request(endpoint, query); }, }); } export default useTodos; ``` -------------------------------- ### Correct Use of `useQuery` Options Source: https://tanstack.com/query/v4/docs/eslint/no-deprecated-options.md These examples show the correct way to use `useQuery` without deprecated options. The `structuralSharing` option is a valid alternative for custom data comparison and sharing logic. ```tsx useQuery({ queryKey: ['todo', todoId], queryFn: () => api.getTodo(todoId), }) ``` ```tsx useQuery({ queryKey: ['todo', todoId], queryFn: () => api.getTodo(todoId), structuralSharing: (oldData, newData) => customCheck(oldData, newData) ? oldData : replaceEqualDeep(oldData, newData), }) ``` -------------------------------- ### Invalidate Queries with a Prefix Source: https://tanstack.com/query/v4/docs/framework/react/guides/query-invalidation.md This example demonstrates how to invalidate all queries whose keys start with `['todos']`. It also shows two `useQuery` hooks that would be affected by this invalidation, ensuring their data is refetched. ```typescript import { useQuery, useQueryClient } from '@tanstack/react-query' // Get QueryClient from the context const queryClient = useQueryClient() queryClient.invalidateQueries({ queryKey: ['todos'] }) // Both queries below will be invalidated const todoListQuery = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList, }) const todoListQuery = useQuery({ queryKey: ['todos', { page: 1 }], queryFn: fetchTodoList, }) ``` -------------------------------- ### Install use-dehydrated-state Package Source: https://tanstack.com/query/v4/docs/framework/react/guides/ssr.md Install the necessary package for managing dehydrated state in your Remix application. ```bash npm i use-dehydrated-state # or pnpm add use-dehydrated-state # or yarn add use-dehydrated-state ``` -------------------------------- ### QueryClientProvider Usage Source: https://tanstack.com/query/v4/docs/framework/react/reference/QueryClientProvider.md Demonstrates how to set up the QueryClientProvider in your React application. You need to create a QueryClient instance and pass it to the provider. ```APIDOC ## QueryClientProvider Use the `QueryClientProvider` component to connect and provide a `QueryClient` to your application: ```tsx import { QueryClient, QueryClientProvider } from '@tanstack/react-query' const queryClient = new QueryClient() function App() { return ... } ``` ### Props - **client** (`QueryClient`) - Required - The QueryClient instance to provide to the application. - **contextSharing** (`boolean`) - Deprecated - Defaults to `false`. - Set this to `true` to enable context sharing across different bundles or microfrontends, ensuring they use the same instance of context. - **context** (`React.Context`) - Optional - Use this to provide a custom React Query context. If not provided, the default context will be used. ``` -------------------------------- ### Initialize QueryClient Source: https://tanstack.com/query/v4/docs/reference/QueryClient.md Instantiate a QueryClient with default options. Configure global query settings like staleTime. ```tsx import { QueryClient } from '@tanstack/react-query' const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: Infinity, }, }, }) await queryClient.prefetchQuery({ queryKey: ['posts'], queryFn: fetchPosts }) ``` -------------------------------- ### Get QueryClient Instance with useQueryClient Source: https://tanstack.com/query/v4/docs/framework/react/reference/useQueryClient.md Import and use the useQueryClient hook to get the QueryClient instance. Optionally provide a custom React Query context. ```tsx import { useQueryClient } from '@tanstack/react-query' const queryClient = useQueryClient({ context }) ``` -------------------------------- ### Install ESLint Plugin Query with Yarn Source: https://tanstack.com/query/v4/docs/framework/react/installation.md Install the ESLint plugin for React Query v4 using Yarn. This helps catch bugs and inconsistencies during development. ```bash yarn add -D @tanstack/eslint-plugin-query@4 ``` -------------------------------- ### Basic React Query Usage Source: https://tanstack.com/query/v4/docs/framework/react/overview.md Demonstrates the fundamental setup and usage of React Query for fetching data. It includes setting up the QueryClient, providing it to the application, and using the useQuery hook to fetch and display data. Ensure the QueryClient is provided at a high level in your component tree. ```tsx import { QueryClient, QueryClientProvider, useQuery, } from '@tanstack/react-query' const queryClient = new QueryClient() export default function App() { return ( ) } function Example() { const { isLoading, error, data } = useQuery({ queryKey: ['repoData'], queryFn: () => fetch('https://api.github.com/repos/TanStack/query').then((res) => res.json(), ), }) if (isLoading) return 'Loading...' if (error) return 'An error has occurred: ' + error.message return (

    {data.name}

    {data.description}

    👀 {data.subscribers_count}{' '} ✨ {data.stargazers_count}{' '} 🍴 {data.forks_count}
    ) } ``` -------------------------------- ### Get the number of fetching queries with useIsFetching Source: https://tanstack.com/query/v4/docs/framework/react/reference/useIsFetching.md Use this hook to get the total number of queries currently fetching. You can also filter by query key to count specific queries. ```tsx import { useIsFetching } from '@tanstack/react-query' // How many queries are fetching? const isFetching = useIsFetching() // How many queries matching the posts prefix are fetching? const isFetchingPosts = useIsFetching({ queryKey: ['posts'] }) ``` -------------------------------- ### Get Mutation Cache Source: https://tanstack.com/query/v4/docs/reference/QueryClient.md Retrieve the mutation cache instance connected to the QueryClient. ```typescript const mutationCache = queryClient.getMutationCache() ``` -------------------------------- ### React App Entry Point Source: https://tanstack.com/query/v4/docs/framework/react/examples/algolia This code sets up the root element for the React application and renders the main App component. Ensure the 'root' element exists in your index.html. ```tsx import ReactDOM from 'react-dom/client' import App from './App' const rootElement = document.getElementById('root') as HTMLElement ReactDOM.createRoot(rootElement).render() ``` -------------------------------- ### Get Query Cache Source: https://tanstack.com/query/v4/docs/reference/QueryClient.md Retrieve the query cache instance connected to the QueryClient. ```typescript const queryCache = queryClient.getQueryCache() ``` -------------------------------- ### Get the Logger Instance Source: https://tanstack.com/query/v4/docs/reference/QueryClient.md Retrieves the logger instance that was configured when the QueryClient was created. ```typescript const logger = queryClient.getLogger() ``` -------------------------------- ### React Root Rendering Source: https://tanstack.com/query/v4/docs/framework/react/examples/playground Initializes the React application by creating a root element and rendering the main application component. This is the standard entry point for a React application. ```javascript const rootElement = document.getElementById('root') ReactDOM.createRoot(rootElement).render() ``` -------------------------------- ### Example Usage of useFocusNotifyOnChangeProps Source: https://tanstack.com/query/v4/docs/framework/react/react-native.md Demonstrates how to use the `useFocusNotifyOnChangeProps` hook with `useQuery` to prevent re-renders when a screen is not in focus. ```typescript import React from 'react' import { Text } from 'react-native' import { useQuery } from '@tanstack/react-query' import { useFocusNotifyOnChangeProps } from './useFocusNotifyOnChangeProps' // Assuming the hook is in this file function MyComponent() { const notifyOnChangeProps = useFocusNotifyOnChangeProps(); const { dataUpdatedAt } = useQuery({ queryKey: ['myKey'], queryFn: async () => { const response = await fetch('https://api.github.com/repos/tannerlinsley/react-query'); return response.json(); }, notifyOnChangeProps, }); return DataUpdatedAt: {dataUpdatedAt}; }; ``` -------------------------------- ### Initialize broadcastQueryClient Source: https://tanstack.com/query/v4/docs/framework/react/plugins/broadcastQueryClient.md Import and use `broadcastQueryClient` by passing your `QueryClient` instance. Optionally, specify a unique `broadcastChannel` name for communication between tabs. ```tsx import { broadcastQueryClient } from '@tanstack/query-broadcast-client-experimental' const queryClient = new QueryClient() broadcastQueryClient({ queryClient, broadcastChannel: 'my-app', }) ``` -------------------------------- ### Get Default QueryClient Options Source: https://tanstack.com/query/v4/docs/reference/QueryClient.md Retrieves the default options that were set when the QueryClient was initialized or updated using `setDefaultOptions`. ```typescript const defaultOptions = queryClient.getDefaultOptions() ``` -------------------------------- ### Get Default Options for Specific Mutations Source: https://tanstack.com/query/v4/docs/reference/QueryClient.md Retrieves the default options configured for mutations matching the provided mutation key. ```typescript const defaultOptions = queryClient.getMutationDefaults(['addPost']) ``` -------------------------------- ### InfiniteQueryObserver Usage Source: https://tanstack.com/query/v4/docs/reference/InfiniteQueryObserver.md Demonstrates how to instantiate and use the InfiniteQueryObserver to subscribe to query results. ```APIDOC ## `InfiniteQueryObserver` The `InfiniteQueryObserver` can be used to observe and switch between infinite queries. ```tsx const observer = new InfiniteQueryObserver(queryClient, { queryKey: ['posts'], queryFn: fetchPosts, getNextPageParam: (lastPage, allPages) => lastPage.nextCursor, getPreviousPageParam: (firstPage, allPages) => firstPage.prevCursor, }) const unsubscribe = observer.subscribe((result) => { console.log(result) unsubscribe() }) ``` **Options** The options for the `InfiniteQueryObserver` are exactly the same as those of [`useInfiniteQuery`](../../framework/react/reference/useInfiniteQuery). ``` -------------------------------- ### Get Query State Source: https://tanstack.com/query/v4/docs/reference/QueryClient.md Use `getQueryState` to synchronously retrieve the state of an existing query. Returns `undefined` if the query does not exist. ```typescript const state = queryClient.getQueryState({ queryKey }) console.log(state.dataUpdatedAt) ``` -------------------------------- ### Instantiate and Subscribe to InfiniteQueryObserver Source: https://tanstack.com/query/v4/docs/reference/InfiniteQueryObserver.md Instantiate an InfiniteQueryObserver with a query client and configuration options, then subscribe to its results. The subscription callback receives the latest query result. Remember to unsubscribe when no longer needed. ```typescript const observer = new InfiniteQueryObserver(queryClient, { queryKey: ['posts'], queryFn: fetchPosts, getNextPageParam: (lastPage, allPages) => lastPage.nextCursor, getPreviousPageParam: (firstPage, allPages) => firstPage.prevCursor, }) const unsubscribe = observer.subscribe((result) => { console.log(result) unsubscribe() }) ``` -------------------------------- ### Check for Active Mutations Source: https://tanstack.com/query/v4/docs/framework/react/reference/useIsMutating.md Use this hook to get the total count of active mutations. You can optionally filter mutations by providing a mutationKey. ```tsx import { useIsMutating } from '@tanstack/react-query' // How many mutations are fetching? const isMutating = useIsMutating() // How many mutations matching the posts prefix are fetching? const isMutatingPosts = useIsMutating({ mutationKey: ['posts'] }) ``` -------------------------------- ### Provide Initial Data with `initialData` Source: https://tanstack.com/query/v4/docs/framework/react/guides/initial-query-data.md Use the `config.initialData` option to set the initial data for a query, skipping the initial loading state. Avoid providing placeholder or incomplete data; use `placeholderData` for such cases. ```tsx const result = useQuery({ queryKey: ['todos'], queryFn: () => fetch('/todos'), initialData: initialTodos, }) ``` -------------------------------- ### Clear the Entire QueryCache Source: https://tanstack.com/query/v4/docs/reference/QueryCache.md Completely clear the query cache, removing all stored queries and their associated data, effectively starting fresh. ```tsx queryCache.clear() ``` -------------------------------- ### Retrieve All Mutations from Cache Source: https://tanstack.com/query/v4/docs/reference/MutationCache.md Get an array of all current mutation instances stored in the MutationCache. This is rarely needed but can be useful for advanced debugging or introspection. ```tsx const mutations = mutationCache.getAll() ``` -------------------------------- ### Basic useQuery Hook Source: https://tanstack.com/query/v4/docs/framework/react/guides/queries.md Demonstrates the basic usage of the useQuery hook with a unique query key and a function that returns a promise. ```tsx import { useQuery } from '@tanstack/react-query' function App() { const info = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList }) } ``` -------------------------------- ### React Root Rendering Source: https://tanstack.com/query/v4/docs/framework/react/examples/playground Initializes the React application by rendering the root component into the DOM. ```javascript const rootElement = document.getElementById('root') ReactDOM.createRoot(rootElement).render() ``` ``` -------------------------------- ### Create a new QueryClient instance Source: https://tanstack.com/query/v4/docs/framework/react/guides/migrating-to-react-query-3.md Instantiate a new QueryClient to manage queries and mutations. A QueryCache and MutationCache are automatically created if not provided. ```tsx import { QueryClient } from 'react-query' const queryClient = new QueryClient() ``` -------------------------------- ### Incorrect useQuery syntax Source: https://tanstack.com/query/v4/docs/eslint/prefer-query-object-syntax.md Examples of incorrect `useQuery` syntax that violate the rule. This includes passing queryKey, queryFn, and options as separate arguments. ```javascript /* eslint "@tanstack/query/prefer-query-object-syntax": "error" */ import { useQuery } from '@tanstack/react-query'; useQuery(queryKey, queryFn, { onSuccess, }); useQuery(queryKey, { queryFn, onSuccess, }); ```