0

I have a query like this:

const query = useMyCustomQuery({ ...someParams });

Which is called on component mount.

Then, in the return of the component I do something like:

{ query.isFetching && <LoadingOverlay /> }

which displays a loading component over it.

Now I need to add a refetchInterval to refetch every 30 seconds. The problem is the loading will be shown while it's refetching and I need for that not to happen, because I want to user to be able to see the list of items even while is refetching.

I know I can change the isFetching to isLoading to show it only on the first load, but I have other user triggered actions that make a refetch and I want those to still have the loading indicator.

Is there any way to differentiate between the two?

3 Answers 3

0

useQuery() has an option called keepPreviousData. what this option do is if you have data from the server it will show them until you get the newest data from the server. Reference to https://tanstack.com/query/v4/docs/react/reference/useQuery

for exmaple:

useQuery({
    queryKey: ["test"],
    queryFn: your_fetch_request,
    keepPreviousData
});
Sign up to request clarification or add additional context in comments.

Comments

0

You could change to isLoading but in addition, on the user actions that you want to force the loading screen on, you could call queryClient.resetQueries({ queryKey }) in order to set it back to its initial state, followed by a refetch -- in the event handler. Take care since resetQueries is async.

I believe this would also force the isLoading back to true.

By doing this you are basically removing the state that was previously fetched, but since you are showing a loading overlay, it sounds like you want to avoid showing anything stale when they force-refresh so that's probably fine.

Comments

0

Update for v5: use placeholderData

You can pass a function to placeholderData that returns previousData to automatically retain the previous data until the new data is available:

const result = useQuery({
  queryKey: ['todos', id],
  queryFn: () => fetch(`/todos/${id}`),
  placeholderData: (previousData, previousQuery) => previousData,
})

https://tanstack.com/query/latest/docs/framework/react/guides/placeholder-query-data#placeholder-data-as-a-function

There is also a keepPreviousData function that is exported from @tanstack/react-query that can be used:

import { keepPreviousData, useQuery } from '@tanstack/react-query'
import React from 'react'

function Todos() {
  const [page, setPage] = React.useState(0)

  const fetchProjects = (page = 0) =>
    fetch('/api/projects?page=' + page).then((res) => res.json())

  const { isPending, isError, error, data, isFetching, isPlaceholderData } =
    useQuery({
      queryKey: ['projects', page],
      queryFn: () => fetchProjects(page),
      placeholderData: keepPreviousData,
    })

  return (
    <div>
      {isPending ? (
        <div>Loading...</div>
      ) : isError ? (
        <div>Error: {error.message}</div>
      ) : (
        <div>
          {data.projects.map((project) => (
            <p key={project.id}>{project.name}</p>
          ))}
        </div>
      )}
      <span>Current Page: {page + 1}</span>
      <button
        onClick={() => setPage((old) => Math.max(old - 1, 0))}
        disabled={page === 0}
      >
        Previous Page
      </button>
      <button
        onClick={() => {
          if (!isPlaceholderData && data.hasMore) {
            setPage((old) => old + 1)
          }
        }}
        // Disable the Next Page button until we know a next page is available
        disabled={isPlaceholderData || !data?.hasMore}
      >
        Next Page
      </button>
      {isFetching ? <span> Loading...</span> : null}
    </div>
  )
}

https://tanstack.com/query/latest/docs/framework/react/guides/paginated-queries#better-paginated-queries-with-placeholderdata

3 Comments

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.