sajad torkamani

In a nutshell

In React Query, a query is a declarative dependency on an asynchronous source of data and is identified by a unique key. You use a query with a Promise-based method to fetch data from a server. To modify data, you use mutations.

An example query

You subscribe to a query in your components or custom hooks by invoking the useQuery hook and passing:

  • A unique query key. This is used for refetching, caching, and sharing queries throughout your app.
  • A function that resolves to some data or that throws an error.
 function Todos() {
   const { isLoading, isError, data, error } = useQuery('todos', fetchTodoList)
 
   if (isLoading) {
     return <span>Loading...</span>
   }
 
   if (isError) {
     return <span>Error: {error.message}</span>
   }
 
   // We can assume by this point that `isSuccess === true`
   return (
     <ul>
       {data.map(todo => (
         <li key={todo.id}>{todo.title}</li>
       ))}
     </ul>
   )
 }

Query states

StateDescription
isLoadingThe query has no data yet and is currently fetching.
isErrorThe query encountered an error.
isSuccessThe query was successful and data is available.
isIdleThe query is currently disabled. This will be true when using dependent queries and you set the enabled option to false.

Query information

PropertyDescription
dataIf the query is in a isSuccess state, this will contain the data.
errorIf the query is in the isError state, this will contain the error.

Query functions

You pass a query function as the second argument to the useQuery hook. The query function is any function that resolves a promise or throws an error whilst attempting to. Here are some examples:

useQuery(['todos'], fetchAllTodos)
useQuery(['todos', todoId], () => fetchTodoById(todoId))
useQuery(['todos', todoId], async () => {
  const data = await fetchTodoById(todoId)
  return data
})
useQuery(['todos', todoId], ({ queryKey }) => fetchTodoById(queryKey[1]))

Any error that’s thrown inside the query function will be available in the error property of the query:

const { error } = useQuery(['todos', todoId], async () => {
   if (somethingGoesWrong) {
     throw new Error('Oh no!')
   }
 
   return data
 })

Query function variables

You can access query keys inside a query function. This makes it easier to extract your query functions like so:

 function Todos({ status, page }) {
   const result = useQuery(['todos', { status, page }], fetchTodoList)
 }
 
 // Access the key, status and page variables in your query function!
 function fetchTodoList({ queryKey }) {
   const [_key, { status, page }] = queryKey
   return new Promise()
 }

Sources