React Query is a library for managing server state in React applications. It provides hooks for fetching, caching, and updating data from APIs or other external sources. React Query helps to streamline data fetching and synchronization with UI components by handling caching, background updates, and other common data management tasks. It’s particularly useful for building complex and data-intensive applications where efficient data fetching and management are crucial.
Core Components of React Query:
1. Queries: Used for fetching data.
2. Mutations: Used for making mutations.
3. Query Invalidation: Mechanism for invalidating or re-fetching queries when necessary.
Steps to Get Started:
Create react project :-
Installation:
Start by creating a React project and installing the @tanstack/react-query package.
React Query DevTools:
Use react query dev tools for debugging.
Configure Query Client:
Create a query client and wrap your application with QueryClientProvider to provide the client to your components.
The QueryClient:
QueryClientProvider:
The QueryClientProvider helps spread the QueryClient across your whole app using React Context. The QueryClient is steady, it’s made just once, so context fits well here. It won’t cause your app to re-render. It simply grants access to the client through useQueryClient.
A vessel that holds the cache:
The QueryClient itself doesn’t really do much. It’s a container for the QueryCache and the Mutation Cache, which are automatically created when you create a new QueryClient.
It also holds some defaults that you can set for all your queries and mutations, and it provides convenience methods to work with the caches. In most situations, you will not interact with the cache directly – you will access it through the QueryClient.
By default, React Query stores data only in-memory, nowhere else. If you refresh your browser page, the cache disappears. To persist the cache, check out the persisters. They allow you to write the cache to external storage like local storage.
Query:
A Query in React Query is where the bulk of the logic resides. It’s not just a container for data. It holds all the details about a query, such as its data, status (like whether it’s fetching or idle), and metadata like when it was last fetched.
The query keeps track of who’s interested in its data and can notify those observers about any changes. This ensures that components relying on query data stay up to date with the latest changes.
Query Observer:
Observers serve as the connection between the Query and the components that need to access its data. When you use the useQuery hook, it creates an Observer that is specifically subscribed to one query. That’s why you need to provide a queryKey when using useQuery.
Active and Inactive Queries:
A Query without an Observer is called an inactive query. It’s still in the cache, but it’s not being used by any component. If you look at the React Query Devtools, you will see that inactive queries are greyed out. The number on the left side indicates the number of observers that are subscribed to the query.
React Query Architecture:
Queries: Queries represent the data-fetching operations in your application. They typically fetch data from a server or another data source. React Query provides hooks like useQuery to execute these queries.
Mutations: Mutations represent operations that modify data, such as creating, updating, or deleting resources on the server. React Query provides hooks like useMutation to perform these operations.
Cache: React Query maintains an internal cache to store the results of queries. This cache is automatically updated and invalidated based on configurable criteria such as time-to-live or manual invalidation.
Query Keys: Query keys are unique identifiers for queries. They are used to retrieve data from the cache and to identify queries when performing operations like invalidation or re-fetching.
Query Status: Queries have different states like loading, error, or success, which allows you to handle UI updates accordingly.
Stale Time:
staleTime determines how long data remains considered “fresh” before it becomes “stale.”
Example:- staleTime: 6000, // Data is considered fresh for 6 seconds. (default 0 sec)
Cache Time:
Data stays in the cache for 60 seconds before potential garbage collection. 60 second queries will be unmounted (default 5 min).
Setting cacheTime and staleTime globally: –
cache Time: 10 * 60 * 1000, // 10 minutes
stale Time: 5 * 60 * 1000, // 5 minutes
Cache time bigger then scale time because you don’t want to make unnecessary network request. if cacheTime smaller then stale, then react query will refetch data form server, this can waste bandwidth and Time.
Polling:
Polling is a technique used to regularly fetch data from a server at fixed intervals. React Query supports polling out of the box, allowing you to automatically refetch data at specific time intervals to keep it up to date.
To enable polling in React Query, you can use the refetchInterval option when defining your query. The refetchInterval specifies the time interval, in milliseconds, for how often the query should be automatically refetched.
refetchInterval:
To automatically refetch data from a query on a specified interval using React Query, you can utilize the refetchInterval option.
Example: refetchInterval: 60000, // Refetch every 60 seconds (1 minute)
useMutation:
React Query, mutations are used to handle actions that modify data on the server, such as creating, updating, or deleting resources.
A mutation can only be in one of the following states at any given moment:
- isIdle or status === ‘idle’ – The mutation is currently idle or in a fresh/reset state
- isPending or status === ‘pending’ – The mutation is currently running
- isError or status === ‘error’ – The mutation encountered an error
- isSuccess or status === ‘success’ – The mutation was successful and mutation data is available
How to Apply dependencies in react query:
Adding userId and filter states as dependencies in React Query ensures that your data fetching remains reactive to changes in these states. By including them in the query key array, React Query automatically re-executes the query whenever either userId or filter changes.
Pagination:
- Efficient Data Fetching: React Query provides efficient data fetching mechanisms, including caching and automatic re-fetching. When paginating through large datasets, these features help minimize unnecessary network requests, improving performance and reducing server load.
- Automatic Cache Management: React Query automatically manages cached data, ensuring that previously fetched pages remain accessible without needing to refetch them. This can significantly enhance the user experience by providing instant access to previously viewed pages.
- Error Handling: React Query simplifies error handling by providing built-in mechanisms for retrying failed requests and displaying error messages. This ensures a robust pagination system that gracefully handles network errors and server failures.
- Optimistic Updates: React Query supports optimistic updates, allowing you to update the UI immediately while the data is being fetched in the background. This feature provides a seamless user experience, especially when navigating between pages with minimal delay.
- Integration with React Components: React Query seamlessly integrates with React components, making it easy to incorporate pagination controls into your application’s UI. This simplifies development and maintenance by leveraging React’s component-based architecture.
Conclusion:
React Query simplifies and streamlines data management in React applications, making it easier to build efficient, scalable, and maintainable applications. Its intuitive API, caching mechanisms, and error handling capabilities make it a valuable tool for developers working on complex front-end projects.