query
🤖 Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.
Top Related Projects
:rocket: A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
React Hooks for Data Fetching
Relay is a JavaScript framework for building data-driven React applications.
The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
The official, opinionated, batteries-included toolset for efficient Redux development
Quick Overview
TanStack Query (formerly React Query) is a powerful data fetching and state management library for web applications. It provides a set of hooks and utilities to simplify the process of fetching, caching, and updating data in React, Vue, Svelte, and Solid applications, with a focus on performance and developer experience.
Pros
- Simplifies complex data fetching and caching scenarios
- Automatic background refetching and stale-while-revalidate functionality
- Supports pagination, infinite scrolling, and optimistic updates out of the box
- Framework agnostic, with adapters for React, Vue, Svelte, and Solid
Cons
- Learning curve for developers new to the concept of query-based state management
- Can be overkill for simple applications with minimal data fetching needs
- Requires careful consideration of caching strategies to avoid unnecessary network requests
- May introduce additional complexity in server-side rendering scenarios
Code Examples
Fetching data with React Query:
import { useQuery } from '@tanstack/react-query'
function Example() {
const { isLoading, error, data } = useQuery({
queryKey: ['todos'],
queryFn: () => fetch('https://api.example.com/todos').then(res => res.json())
})
if (isLoading) return 'Loading...'
if (error) return 'An error has occurred: ' + error.message
return (
<ul>
{data.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
)
}
Mutation example:
import { useMutation, useQueryClient } from '@tanstack/react-query'
function AddTodo() {
const queryClient = useQueryClient()
const mutation = useMutation({
mutationFn: newTodo => {
return fetch('https://api.example.com/todos', {
method: 'POST',
body: JSON.stringify(newTodo),
})
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
})
return (
<form onSubmit={(e) => {
e.preventDefault()
mutation.mutate({ title: 'New Todo' })
}}>
<button type="submit">Add Todo</button>
</form>
)
}
Infinite query example:
import { useInfiniteQuery } from '@tanstack/react-query'
function InfiniteList() {
const {
data,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
} = useInfiniteQuery({
queryKey: ['projects'],
queryFn: ({ pageParam = 0 }) =>
fetchProjects(pageParam),
getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
})
return (
<div>
{data.pages.map((group, i) => (
<React.Fragment key={i}>
{group.projects.map(project => (
<p key={project.id}>{project.name}</p>
))}
</React.Fragment>
))}
<button
onClick={() => fetchNextPage()}
disabled={!hasNextPage || isFetchingNextPage}
>
{isFetchingNextPage
? 'Loading more...'
: hasNextPage
? 'Load More'
: 'Nothing more to load'}
</button>
</div>
)
}
Getting Started
To start using TanStack Query in a React project:
-
Install the package:
npm install @tanstack/react-query
-
Wrap your app with QueryClientProvider:
import { QueryClient, QueryClientProvider } from '@tanstack/react-query' const queryClient = new QueryClient() function App() { return ( <QueryClientProvider client={queryClient}>
Competitor Comparisons
:rocket: A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
Pros of Apollo Client
- Specialized for GraphQL with built-in caching and state management
- Extensive ecosystem with tools like Apollo DevTools and Apollo Studio
- Strong TypeScript support with automatic type generation
Cons of Apollo Client
- Steeper learning curve, especially for developers new to GraphQL
- Larger bundle size compared to TanStack Query
- More opinionated, which can limit flexibility in some scenarios
Code Comparison
Apollo Client:
const GET_DOGS = gql`
query GetDogs {
dogs {
id
breed
}
}
`;
function Dogs() {
const { loading, error, data } = useQuery(GET_DOGS);
if (loading) return 'Loading...';
if (error) return `Error! ${error.message}`;
return data.dogs.map(dog => <Dog key={dog.id} dog={dog} />);
}
TanStack Query:
const fetchDogs = async () => {
const response = await fetch('/api/dogs');
return response.json();
};
function Dogs() {
const { isLoading, error, data } = useQuery('dogs', fetchDogs);
if (isLoading) return 'Loading...';
if (error) return 'An error has occurred: ' + error.message;
return data.map(dog => <Dog key={dog.id} dog={dog} />);
}
Both libraries provide similar functionality for data fetching and state management, but Apollo Client is more tightly integrated with GraphQL, while TanStack Query offers a more flexible approach that can work with any data fetching method.
React Hooks for Data Fetching
Pros of SWR
- Lightweight and minimalistic API, easier to get started with
- Built-in support for real-time and optimistic updates
- Seamless integration with Next.js and Vercel ecosystem
Cons of SWR
- Less flexible configuration options compared to Query
- Limited support for advanced caching strategies
- Smaller ecosystem and fewer plugins/extensions
Code Comparison
SWR:
import useSWR from 'swr'
function Profile() {
const { data, error } = useSWR('/api/user', fetcher)
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
return <div>hello {data.name}!</div>
}
Query:
import { useQuery } from '@tanstack/react-query'
function Profile() {
const { data, isLoading, error } = useQuery(['user'], fetchUser)
if (error) return <div>failed to load</div>
if (isLoading) return <div>loading...</div>
return <div>hello {data.name}!</div>
}
Both libraries offer similar functionality for data fetching and caching, but Query provides more advanced features and configuration options. SWR is simpler and integrates well with Next.js, while Query offers greater flexibility and a larger ecosystem. The choice between them depends on project requirements and complexity.
Relay is a JavaScript framework for building data-driven React applications.
Pros of Relay
- Optimized for GraphQL, providing deep integration and efficient data fetching
- Supports declarative data dependencies, allowing components to specify their data needs
- Offers powerful features like automatic query batching and caching
Cons of Relay
- Steeper learning curve due to its complex architecture and concepts
- Requires a specific GraphQL server setup, limiting flexibility
- Less suitable for smaller projects or those not using GraphQL
Code Comparison
Relay:
const RepositoryNameFragment = graphql`
fragment RepositoryName_repository on Repository {
name
}
`;
function RepositoryName(props) {
const data = useFragment(RepositoryNameFragment, props.repository);
return <div>{data.name}</div>;
}
TanStack Query:
const { data } = useQuery('repositoryName', fetchRepositoryName);
function RepositoryName() {
return <div>{data.name}</div>;
}
Summary
Relay excels in GraphQL-based applications, offering deep integration and powerful features. However, it comes with a steeper learning curve and specific server requirements. TanStack Query provides a more flexible and easier-to-adopt solution for various data fetching scenarios, including REST APIs, making it suitable for a wider range of projects.
The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
Pros of urql
- Lightweight and modular design, allowing for smaller bundle sizes
- Built-in GraphQL-specific features like normalized caching and subscriptions
- Simpler API with less boilerplate code for basic GraphQL operations
Cons of urql
- Less flexible for non-GraphQL data fetching scenarios
- Smaller ecosystem and community compared to Query
- Limited built-in devtools and debugging capabilities
Code Comparison
urql:
import { useQuery } from 'urql';
const TodosQuery = `
query {
todos {
id
title
}
}
`;
function Todos() {
const [result] = useQuery({ query: TodosQuery });
// ... render todos
}
Query:
import { useQuery } from '@tanstack/react-query';
function Todos() {
const { data, isLoading } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodos,
});
// ... render todos
}
urql is specifically designed for GraphQL, offering a more streamlined API for GraphQL operations. Query, on the other hand, is more versatile and can handle various data fetching scenarios beyond GraphQL. Query also provides a more robust set of features for managing complex data fetching states and caching strategies, making it a better choice for larger applications with diverse data requirements. However, for projects primarily focused on GraphQL, urql's simplicity and GraphQL-specific optimizations may be advantageous.
The official, opinionated, batteries-included toolset for efficient Redux development
Pros of Redux Toolkit
- Provides a standardized way to write Redux logic, reducing boilerplate code
- Includes utilities for common Redux use cases, like creating slices and thunks
- Offers better integration with the Redux ecosystem and dev tools
Cons of Redux Toolkit
- Steeper learning curve for beginners due to Redux concepts and patterns
- Can be overkill for simpler applications or those with minimal state management needs
- Requires more setup and configuration compared to Query's simpler API
Code Comparison
Redux Toolkit:
const counterSlice = createSlice({
name: 'counter',
initialState: 0,
reducers: {
increment: state => state + 1,
},
});
Query:
const useCounter = () => {
const [count, setCount] = useState(0);
const increment = () => setCount(prev => prev + 1);
return { count, increment };
};
Key Differences
- Redux Toolkit is focused on global state management, while Query specializes in data fetching and caching
- Query provides out-of-the-box support for server-state synchronization, which Redux Toolkit doesn't offer directly
- Redux Toolkit requires more boilerplate code but offers more control over state updates
- Query has a simpler API and is easier to integrate into existing projects without major architectural changes
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Hooks for fetching, caching and updating asynchronous data in React, Solid, Svelte and Vue
Enjoy this library? Try the entire TanStack! TanStack Table, TanStack Router, TanStack Virtual, React Charts, React Ranger
Visit tanstack.com/query for docs, guides, API and more!
Still on React Query v2? No problem! Check out the v2 docs here: https://github.com/TanStack/query/tree/2.x/docs/src/pages/docs.
Still on React Query v3? No problem! Check out the v3 docs here: https://tanstack.com/query/v3/docs/.
Still on React Query v4? No problem! Check out the v4 docs here: https://tanstack.com/query/v4/docs/.
Quick Features
- Transport/protocol/backend agnostic data fetching (REST, GraphQL, promises, whatever!)
- Auto Caching + Refetching (stale-while-revalidate, Window Refocus, Polling/Realtime)
- Parallel + Dependent Queries
- Mutations + Reactive Query Refetching
- Multi-layer Cache + Automatic Garbage Collection
- Paginated + Cursor-based Queries
- Load-More + Infinite Scroll Queries w/ Scroll Recovery
- Request Cancellation
- React Suspense + Fetch-As-You-Render Query Prefetching
- Dedicated Devtools
Contributing
View the contributing guidelines here
Become a Sponsor!
Top Related Projects
:rocket: A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
React Hooks for Data Fetching
Relay is a JavaScript framework for building data-driven React applications.
The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
The official, opinionated, batteries-included toolset for efficient Redux development
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot