12

I have a requirement to keep fetching data until a condition is met I can set up the fetch on an interval with the snippet below but I can't figure out how to stop the fetchData when needed. Is this possible?

const { status: answersStatus, data: answers } = useQuery(
                           ['fetchData', { context, activity, stage, country }], 
                           fetchData,
                           {refetchInterval: 2000});

5 Answers 5

18

update:

since react-query v3.25.0, refetchInterval can accept a function to accommodate this use-case better:

refetchInterval: data => (isConditionMet(data) ? false : 2000)

original answer:

with a local state:

const [refetchInterval, setRefetchInterval] = React.useState(2000)
const { status: answersStatus, data: answers } = useQuery(
    ['fetchData', { context, activity, stage, country }], 
    fetchData,
    {refetchInterval});

you can set the refetchInterval to false or 0 to turn it off. If you want to do it depending on the response, the onSuccess, onError or onSettled callbacks are likely the best place:

const [refetchInterval, setRefetchInterval] = React.useState(2000)
const { status: answersStatus, data: answers } = useQuery(
    ['fetchData', { context, activity, stage, country }], 
    fetchData,
    {
        refetchInterval,
        onError: () => setRefetchInterval(0)
    });
Sign up to request clarification or add additional context in comments.

4 Comments

I prefer the use of the refetchInterval: data => (checkMyResponseHere(data) ? false : 2000) function because it doesn't require state
you're right - I've written this answer before I added the refetchInterval-as-a-function feature. I've updated the answer.
How do you add type on this one? Mine is yelling
this appears to make an extra call, i think when the refetchInterval is set it makes another query. i can see more calls in my network tab with the refetchInterval function and think the onError is more efficient.
7

As of Tanstack Query v5, the signature has changed from

refetchInterval: number | false | ((data: TData | undefined, query: Query) => number | false)

to

refetchInterval: number | false | ((query: Query) => number | false | undefined)

So instead of doing

refetchInterval: data => (isConditionMet(data) ? false : 2000)

like in TkDodo's answer, you'll need to do:

refetchInterval: query => (isConditionMet(query.state.data) ? false : 2000)

2 Comments

thank you for putting the effort of mentioning this here!
thanks I went all over the place and followed TKDodo's answer until scrolling down :/
6

For me, it was causing infinite loop until passing function to the refetchInterval like so:

refetchInterval: data => (checkMyResponseHere(data) ? false : 2000)

P.S. react-query v.3.38.0

2 Comments

This works! thanks dude. Funny this doesn't show up in the React Query docs
it's in the api docs: refetchInterval: number | false | ((data: TData | undefined, query: Query) => number | false)
1

In the end I leveraged short-circuit evaluation so my call is now

const { data: answers } = useQuery(
    isThereSomethingToGet && [`fetchData`, { ...qmfRouteParams, context: appContext }],
    fetchData,
    {
      refetchIntervalInBackground: true,
      refetchInterval: DocusignPolling.INTERVAL,
    },
  );

When isThereSomethingToGet is falsy the function isn't called.

2 Comments

react-query is not stopping the execution of the queryFn due to falsy query keys (not on v3 at least). to disable a query, you need to set the enabled boolean to false.
@TkDodo Is there a way to prevent fetching when refetch method get called?
0

With React Query v4, you need to pass the 'refetchInterval' like below:

useQuery({ queryKey: ['todos'], queryFn: ()=>{}, refetchInterval: (data)=> data.refetchNeeded? 5000: false })

Here, refetchNeeded is the boolean field from the previously fetched data.

Comments

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.