🖍️
Developer Note
  • Welcome
  • Git
    • Eslint & Prettier & Stylelint & Husky
  • Programming Language
    • JavaScript
      • Script Async vs Defer
      • Module
      • Const VS Let VS Var
      • Promise
      • Event Loop
      • Execution Context
      • Hoisting
      • Closure
      • Event Buddling and Capturing
      • Garbage Collection
      • This
      • Routing
      • Debounce and Throttle
      • Web Component
      • Iterator
      • Syntax
      • String
      • Array
      • Object
      • Proxy & Reflect
      • ProtoType
      • Class
      • Immutability
      • Typeof & Instanceof
      • Npm (Node package manager)
    • TypeScript
      • Utility Type
      • Type vs Interface
      • Any vs Unknown vs Never
      • Void and undefined
      • Strict Mode
      • Namespace
      • Enum
      • Module
      • Generic
    • Python
      • Local Development
      • Uv
      • Asyncio & Event loop
      • Context Manager
      • Iterator & Generator
      • Fast API
      • Pydantic & Data Class
    • Java
      • Compilation and Execution
      • Data Type
      • Enumeration
      • Data Structure
      • Try Catch
      • InputStream and OutputStream
      • Concurrent
      • Unicode Block
      • Build Tools
      • Servlet
      • Java 8
  • Coding Pattern
    • MVC vs MVVM
    • OOP vs Functional
    • Error Handling
    • MVC vs Flux
    • Imperative vs Declarative
    • Design Pattern
  • Web Communication
    • REST API
      • Web Hook
      • CORS issue
    • HTTPS
    • GraphQL
      • REST API vs GraphQL
      • Implementation (NodeJS + React)
    • Server-Sent Event
    • Web Socket
    • IP
    • Domain Name System (DNS)
  • Frontend
    • Progressive Web App (PWA)
    • Single Page & Multiple Page Application
    • Search Engine Optimiaztion (SEO)
    • Web bundling & Micro-frontend
      • Webpack
        • Using Webpack to build React Application
        • Using Webpack to build react library
      • Vite
      • Using rollup to build react library
      • Implementing micro frontend
    • Web Security
      • CSRF & Nonce
      • XSS
      • Click hijacking
    • Cypress
    • CSS
      • Core
        • Box Model
        • Inline vs Block
        • Flexbox & Grid
        • Pseudo Class
        • Position
      • Tailwind CSS
        • Shadcn
      • CSS In JS
        • Material UI
    • React
      • Core
        • Component Pattern
        • React Lazy & Suspense
        • React Portal
        • Error Boundary
        • Rendering Methods
        • Environment Variable
        • Conditional CSS
        • Memo
        • Forward Reference
        • High Order Component (HOC) & Custom Hook
        • TypeScript
      • State Management
        • Redux
        • Recoil
        • Zustand
      • Routing
        • React Router Dom
      • Data Fetching
        • Axios & Hook
        • React Query
        • Orval
      • Table
        • React Table
      • Form & Validation
        • React Hook Form
        • Zod
      • NextJS
        • Page Router
        • App Router
      • React Native
    • Angular
    • Svelte
      • Svelte Kit
  • Backend
    • Cache
      • Browser Cache
      • Web Browser Storage
      • Proxy
      • Redis
    • Rate limit
    • Monitoring
      • Logging
      • Distributed Tracing
    • Load Test
    • Encryption
    • Authentication
      • Password Protection
      • Cookie & Session
      • JSON Web Token
      • SSO
        • OAuth 2.0
        • OpenID Connect (OIDC)
        • SAML
    • Payment
      • Pre-built
      • Custom
    • File Handling
      • Upload & Download (Front-end)
      • Stream & Buffer
    • Microservice
      • API Gateway
      • Service Discovery
      • Load Balancer
      • Circuit Breaker
      • Message Broker
      • BulkHead & Zipkin
    • Elastic Search
    • Database
      • SQL
        • Group By vs Distinct
        • Index
        • N + 1 problem
        • Normalization
        • Foreign Key
        • Relationship
        • Union & Join
        • User Defined Type
      • NOSQL (MongoDB)
      • Transaction
      • Sharding
      • Lock (Concurrency Control)
    • NodeJS
      • NodeJS vs Java Spring
      • ExpressJS
      • NestJS
        • Swagger
        • Class Validator & Validation Pipe
        • Passport (Authentication)
      • Path Module
      • Database Connection
        • Integrating with MYSQL
        • Sequalize
        • Integrating with MongoDB
        • Prisma
        • MikroORM
        • Mongoose
      • Streaming
      • Worker Thread
      • Passport JS
      • JSON Web Token
      • Socket IO
      • Bull MQ
      • Pino (Logging)
      • Yeoman
    • Spring
      • Spring MVC
      • Spring REST
      • Spring Actuator
      • Aspect Oriented Programming (AOP)
      • Controller Advice
      • Filter
      • Interceptor
      • Concurrent
      • Spring Security
      • Spring Boot
      • Spring Cloud
        • Resilience 4j
      • Quartz vs Spring Batch
      • JPA and Hibernate
      • HATEOS
      • Swagger
      • Unit Test (Java Spring)
      • Unit Test (Spring boot)
  • DevOp
    • Docker
    • Kubernetes
      • Helm
    • Nginx
    • File System
    • Cloud
      • AWS
        • EC2 (Virtual Machine)
        • Network
        • IAM
          • Role-Service Binding
        • Database
        • Route 53
        • S3
        • Message Queue
        • Application Service
        • Serverless Framework
        • Data Analysis
        • Machine Learning
        • Monitoring
        • Security
      • Azure
        • Identity
        • Compute Resource
        • Networking
        • Storage
        • Monitoring
      • Google Cloud
        • IAM
          • Workload Identity Federation
        • Compute Engine
        • VPC Network
        • Storage
        • Kubernetes Engine
        • App Engine
        • Cloud function
        • Cloud Run
        • Infra as Code
        • Pub/Sub
    • Deployment Strategy
    • Jenkins
    • Examples
      • Deploy NextJS on GCP
      • Deploy Spring on Azure
      • Deploy React on Azure
  • Domain Knowledge
    • Web 3
      • Blockchain
      • Cryptocurrency
    • AI
      • Prompt
      • Chain & Agent
      • LangChain
      • Chunking
      • Search
      • Side Products
Powered by GitBook
On this page
  • Introduction
  • Fresh & Stale State
  • Default Behavior
  • Query Cancellation
  • Setup Provider
  • UseQuery
  • UseMutation

Was this helpful?

  1. Frontend
  2. React
  3. Data Fetching

React Query

Introduction

  • The library to handle data fetching, including retry, caching, error handling, so as to reduce the boilerplate code

  • Convenient to create custom hook to fetching or updating data in order to achieve separate of concern

Fresh & Stale State

  • Fresh: all the data must come from cache, no background refetching will be happened

  • Stale: data can still come from cache, but the background refetching can be happened

Default Behavior

  • Stale queries are refetched automatically in the background when:

    • New instances of the query mount

    • The window is refocused

    • The network is reconnected.

    • The query is optionally configured with a refetch interval.

  • If Query fails, will silently retry 3 times

  • The data of the inactive queries will be cached for 5 mins

  • The staleTime is 0

  • isLoading: Your query has no data and is currently loading for the first time

  • isFetching flag is not part of the internal state machine - it is an additional flag that will be true whenever a request is in-flight. You can be fetching and success, you can be fetching and error - but you cannot be loading and success at the same time.

  • React Query will attempt to compare the old state and the new and keep as much of the previous state as possible to prevent trivial re-rendering

Query Cancellation

  • Queries that unmount or become unused will be cancelled if you consume the AbortSignal or attach a cancel function to your Promise, the Promise will be cancelled (e.g. aborting the fetch)

import axios from 'axios'

const query = useQuery('todos', ({ signal }) =>
  axios.get('/todos', {
    // Pass the signal to `axios`
    signal,
  })
)
import axios from 'axios'

const query = useQuery('todos', () => {
  // Create a new CancelToken source for this request
  const CancelToken = axios.CancelToken
  const source = CancelToken.source()

  const promise = axios.get('/todos', {
    // Pass the source token to your request
    cancelToken: source.token,
  })

  // Cancel the request if React Query calls the `promise.cancel` method
  promise.cancel = () => {
    source.cancel('Query was cancelled by React Query')
  }

  return promise
})
  • The query can also be cancelled manually

const [queryKey] = useState('todos')

const query = useQuery(queryKey, async ({ signal }) => {
  const resp = await fetch('/todos', { signal })
  return resp.json()
})

const queryClient = useQueryClient()

return (
  <button onClick={(e) => {
    e.preventDefault()
    queryClient.cancelQueries(queryKey)
   }}>Cancel</button>
)

Setup Provider

  • To set up the provider for children, so that react-query can be used in component

  • To customize the default setting for library

import axios from "axios";
import { ReactNode } from "react";
import {
  DefaultOptions,
  QueryClient,
  QueryClientProvider as Provider,
} from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";

const defaultOptions: DefaultOptions = {
  queries: {
    refetchOnReconnect: false,
    refetchOnWindowFocus: false,
    retry: (failureCount, error) =>
      failureCount < 3 &&
      !(axios.isAxiosError(error) && error?.response?.status === 401),
  },
};

const queryClient = new QueryClient({ defaultOptions });

interface QueryClientProviderProps {
  children: ReactNode;
}

export default function QueryClientProvider({
  children,
}: QueryClientProviderProps) {
  return (
    <Provider client={queryClient}>
      {children}
      <ReactQueryDevtools initialIsOpen={false} />
    </Provider>
  );
}
export default function App(){
    <QueryClientProvider>
        {children}
    </QueryClientProvider>
}

UseQuery

  • Handle fetching data when the page is mounted and the dependencies are changed

  • Data will be cached based on the query key

interface PageListApiResponse {
  results: Page[];
  maxPublishedPages: number;
}

export default function usePageListQuery(
  state: PageState,
  offset: number,
  options: UseQueryOptions<PageListApiResponse, AxiosError<any>> = {}
) {
  const axios = useContext(AxiosContext);

  return useQuery({
    queryKey: ["pageList", offset, state],
    queryFn: async ({ queryKey }) => {
      const { data } = await axios.get<PageListApiResponse>(
        `${process.env.REACT_APP_API_URL}/pages?_limit=10&_start=${queryKey[1]}&state=${queryKey[2]}`
      );
      return data;
    },
    ...options,
  });
}
const {
    data: { results: listPagesData = [], maxPublishedPages = 0 } = {},
    isLoading,
    isFetching,
    refetch,
  } = usePageListQuery(listingStatus, pageOffset, {
    onSuccess:(data)=> {...},
    onError: (err)=> {...},
    enabled: allCountData && allCountData.count > 0,
    select: ({ results, ...data }) => ({
      ...data,
      results: [...results].sort((a, b) => {
        if (a.url === homePageSettings?.home) return -1;
        if (b.url === homePageSettings?.home) return 1;
        return 0;
      }),
    }),
  });

UseMutation

  • Used to update data

export default function usePageUpdateMutation({
  onSuccess,
  ...options
}: MutationOptions<AxiosResponse<Page>, AxiosError<any>, Page> = {}) {
  const axios = useContext(AxiosContext);
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (page: Page) =>
      axios.put<Page>(
        `${process.env.REACT_APP_API_URL}/pages/${page.id}`,
        page
      ),
    onSuccess: (data, variables, context) => {
      if (onSuccess) onSuccess(data, variables, context);
      // to clear the query, 
      // so that the query will be loaded again and trigger isLoading
      queryClient.invalidateQueries("allPageList");
      queryClient.invalidateQueries(["page", variables.id]);
      // set the data to the existing query directly
      queryClient.setQueryData(['test', variables.id], data)
    },
    ...options,
  });
}
PreviousAxios & HookNextOrval

Last updated 5 days ago

Was this helpful?

LogoStatus Checks in React Query
LogoQuery Cancellation | TanStack Query React Docstannerlinsley
LogoReact Query Render Optimizations
LogoReact Query as a State Manager
LogoReact Query and TypeScript
LogoEffective React Query Keys
LogoMastering Mutations in React Query