19

I'm using react-query v3.13 to fetch data from API.
What I want to do is to fetch API regularly from a certain point (for example, when clicking the start button), not from the time of calling useQuery.

I tried the following ways.

  • set enabled property to false to disable automatic querying but it also disables re-fetching.
    I could not find a way to re-enable/set the enabled property to true. And I had to use setTimeout by myself to re-fetch regularly.
  • keep enabled property as true but I could not find a way to disable the initial fetching.

Is there any proper way to do this?

1
  • I remember there was the forceFetchOnMount property in the previous version, but it's replaced by refetchOnMount in version 3. Commented Mar 23, 2021 at 3:52

4 Answers 4

21

if you hardcode the enabled option to false, you can still use the refetch method you get back from useQuery to imperatively trigger a fetch. But the query will still be disabled, so no background updates.

if you want a lazy that is disabled, but enables when you call a function, the best way would be with a simple abstraction over useQuery with a local state:

const useLazyQuery = (key, fn, options) => {
  const [enabled, setEnabled] = useState(false)
  return [() => setEnabled(true), useQuery(key, fn, { ...options, enabled })]
}
Sign up to request clarification or add additional context in comments.

3 Comments

Is there anyway to do similar using queryClient?
I think you can have a disabled query and still do queryClient.refetchQueries(key) - this is similar to the refetch method returned from useQuery
Is there a way to prevent fetching when refetch method get called?
6

For those coming to this post for disabling fetch on mount, especially in a server actions context where you are fetching initial data on the server side, the fix for me was to set refetchOnMount: false.

const { data, isLoading, refetch } = useQuery({
  queryKey: [`todo`, id],
  queryFn: () => actions.getTodo(id),
  initialData: initialTodo,
  refetchOnMount: false,
});

Comments

0

I found "don't fetch on load or mount" especially common for queries associated with pop-ups or dialogs. A common scenario is when you don't want to fetch data on component mount or initial load, but rather when a specific UI element (like a dialog) is opened.

The solution that worked for me is to bind a variable to the dialog state and use it to control when the query is enabled. This means:

  1. It fetches data only when the dialog or popup is opened.
  2. It continues to refetch when query keys change or data becomes invalid, but only while the dialog remains open.
  3. It prevents unnecessary API calls when the dialog is closed.

Implementation

import { useState } from 'react';
import { useQuery } from 'react-query';

function YourComponent() {
  const [isOpen, setIsOpen] = useState(false);

  const { data, isPending, isError, error, refetch } = useQuery({
    queryKey: [promptId, inputValue],
    queryFn: async () => {
      const data = await // Your API call here
      return data;
    },
    // Note that we pass isOpen to enabled instead of `true` or `false`
    enabled: isOpen,
  });

  // Rest of your component logic
}

A breakdown of what it means when enabled option in the useQuery hook is set to isOpen:

  • The query will only run when isOpen is true (i.e., when the dialog is opened).
  • If the dialog is closed (isOpen is false), the query won't run, saving unnecessary API calls.
  • When the dialog is open, the query will behave normally, refetching when query keys change or data becomes invalid.

1 Comment

How do you pass in isOpen, it's hard coded in the state right there
-3
import { useBoolean } from "@chakra-ui/react";
import { useQuery } from "@tanstack/react-query";

function useLazyQuery(queryKey, {queryFn, onError}) {
  const [Enable, setEnable] = useBoolean(false);

  const Get = useQuery(queryKey, {
    queryFn,
    onError: typeof onError === "function" && onError,
    enabled: Enable, // Habilitar la consulta solo si el filtro no está vacío
  });

  return { ...Get, enable: setEnable.on, disable: setEnable.off };
}

export default useLazyQuery;

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.