reactjsreact-query

useQuery React still fires when enabled is false


I am having an issue when I try to execute dependent query.

This is the code of the component that only show info from the API REST using react-query, even when the enabled is set to false i am seeing on the browser

Browser tools:

GET https://localhost:7065/api/Location/cityById/undefined
[HTTP/2 400  226ms]

XHRGET
https://localhost:7065/api/Location/parishById/undefined
[HTTP/2 400  212ms]

XHRGET
https://localhost:7065/api/Location/townShipById/undefined
[HTTP/2 400  128ms]

XHRGET
https://localhost:7065/api/Location/zoneTypeById/undefined
[HTTP/2 400  181ms]

XHRGET
https://localhost:7065/api/Location/cityById/undefined
[HTTP/2 400  209ms]

XHRGET
https://localhost:7065/api/Location/parishById/undefined
[HTTP/2 400  155ms]

XHRGET
https://localhost:7065/api/Location/zoneTypeById/undefined
[HTTP/2 400  232ms]

XHRGET
https://localhost:7065/api/Location/townShipById/undefined

Code of component:

import { useQuery } from "@tanstack/react-query";
import { useRegisterFormViewContext } from "../providers/registerFormViewProvider";
import { useAuth } from "../hooks/useAuth";
import { GetStoreDetailService } from "../services/storeDetailService";
import { GetEstimateService } from "../services/estimateService";
import {
  GetCityByIdService,
  GetParishedByIdService,
  GetStatesService,
  GetTwonShipByIdService,
  GetZoneTypesByIdService,
} from "../services/locationSerivce";

function ViewStoreDetail() {
  const { storedValue } = useAuth();

  const [state] = useRegisterFormViewContext();

  const { data: viewDetailStore, isPending: isPendingViewDetailStore } =
    useQuery({
      queryKey: ["viewStoreDetail"],
      queryFn: GetStoreDetailService(
        storedValue,
        state.select_store_id.select_store_id,
      ),
      staleTime: 0,
      enabled: true,
    });

  const { data: estimateData, isPending: isPendingEstimateData } = useQuery({
    queryKey: ["viewStoreDetailEstimate"],
    queryFn: GetEstimateService(storedValue),
    staleTime: 0,
    enabled: true,
  });

  const { data: states, isPending: isPendingStates } = useQuery({
    queryKey: ["viewStoreDetailStates"],
    queryFn: GetStatesService(storedValue),
    staleTime: 0,
    enabled: true,
  });

  const cityId = viewDetailStore?.std_dir_city_id;

  const { data: city, isPending: isPendingCity } = useQuery({
    enabled: false,
    queryKey: ["viewStoreDetailCity", cityId],
    queryFn: GetCityByIdService(storedValue, cityId),
    staleTime: 0,
  });

  const parishedId = viewDetailStore?.std_dir_parroquia_id;

  const { data: parished, isPending: isPendingParisged } = useQuery({
    enabled: false,
    queryKey: ["viewStoreDetailParished", parishedId],
    queryFn: GetParishedByIdService(storedValue, parishedId),
    staleTime: 0,
  });

  const townshipId = parished?.par_tow_id;

  const { data: township, isPending: isPendingTownShip } = useQuery({
    enabled: false,
    queryKey: ["viewStoreDetailTownship", townshipId],
    queryFn: GetTwonShipByIdService(storedValue, townshipId),
    staleTime: 0,
  });

  const transportId = viewDetailStore?.std_dir_zone_type_id;

  const { data: transportType, isPending: isPendingTransportType } = useQuery({
    enabled: false,
    queryKey: ["viewStoreDetailTransporType", transportId],
    queryFn: GetZoneTypesByIdService(storedValue, transportId),
    staleTime: 0,
  });

  return (
    <div className="h-[calc(100vh-64px)] border-2 border-black">
      SHOW information of the queries in the future...
    </div>
  );
}

export default ViewStoreDetail;

Here are my API calls:

import { GetBaseUrl } from "./apiBaseUrl";

export async function GetStatesService(storedValue) {
  try {
    const response = await fetch(GetBaseUrl() + "api/Location/states", {
      method: "GET",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json; charset=UTF-8",
        Authorization: `Bearer ${storedValue}`,
      },
    });

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

    return response.json();
  } catch (error) {
    throw new Error("Obtener estados fallo: " + error.message);
  }
}

export async function GetCitiesByStateService(storedValue, stateId) {
  try {
    const response = await fetch(
      GetBaseUrl() + `api/Location/citiesByState/${stateId}`,
      {
        method: "GET",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json; charset=UTF-8",
          Authorization: `Bearer ${storedValue}`,
        },
      },
    );

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

    return response.json();
  } catch (error) {
    throw new Error("Obtener ciudades fallo: " + error.message);
  }
}

export async function GetCityByIdService(storedValue, cityId) {
  try {
    const response = await fetch(
      GetBaseUrl() + `api/Location/cityById/${cityId}`,
      {
        method: "GET",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json; charset=UTF-8",
          Authorization: `Bearer ${storedValue}`,
        },
      },
    );

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

    return response.json();
  } catch (error) {
    throw new Error("Obtene ciudad fallo: " + error.message);
  }
}

export async function GetTwonShipsByStateService(storedValue, stateId) {
  try {
    const response = await fetch(
      GetBaseUrl() + `api/Location/townShipsByState/${stateId}`,
      {
        method: "GET",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json; charset=UTF-8",
          Authorization: `Bearer ${storedValue}`,
        },
      },
    );

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

    return response.json();
  } catch (error) {
    throw new Error("Obtener municipios fallo: " + error.message);
  }
}

export async function GetTwonShipByIdService(storedValue, twonShipId) {
  try {
    const response = await fetch(
      GetBaseUrl() + `api/Location/townShipById/${twonShipId}`,
      {
        method: "GET",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json; charset=UTF-8",
          Authorization: `Bearer ${storedValue}`,
        },
      },
    );

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

    return response.json();
  } catch (error) {
    throw new Error("Obtene municipio fallo: " + error.message);
  }
}

export async function GetParishedByTownShipService(storedValue, townShipId) {
  try {
    const response = await fetch(
      GetBaseUrl() + `api/Location/parishesByTownShip/${townShipId}`,
      {
        method: "GET",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json; charset=UTF-8",
          Authorization: `Bearer ${storedValue}`,
        },
      },
    );

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

    return response.json();
  } catch (error) {
    throw new Error("Obtener parroquias fallo: " + error.message);
  }
}

export async function GetParishedByIdService(storedValue, parishedId) {
  try {
    const response = await fetch(
      GetBaseUrl() + `api/Location/parishById/${parishedId}`,
      {
        method: "GET",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json; charset=UTF-8",
          Authorization: `Bearer ${storedValue}`,
        },
      },
    );

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

    return response.json();
  } catch (error) {
    throw new Error("Obtene parroquia fallo: " + error.message);
  }
}

export async function GetZoneTypesService(storedValue) {
  try {
    const response = await fetch(GetBaseUrl() + "api/Location/zoneTypes", {
      method: "GET",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json; charset=UTF-8",
        Authorization: `Bearer ${storedValue}`,
      },
    });

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

    return response.json();
  } catch (error) {
    throw new Error("Obtener tipos de zonas fallo: " + error.message);
  }
}

export async function GetZoneTypesByIdService(storedValue, zoneTypeId) {
  try {
    const response = await fetch(
      GetBaseUrl() + `api/Location/zoneTypeById/${zoneTypeId}`,
      {
        method: "GET",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json; charset=UTF-8",
          Authorization: `Bearer ${storedValue}`,
        },
      },
    );

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

    return response.json();
  } catch (error) {
    throw new Error("Obtener tipo de zona fallo: " + error.message);
  }
}

Here is my App.jsx:

import { createBrowserRouter, RouterProvider } from "react-router-dom";
import Homepage from "./pages/Homepage";
import Login from "./pages/Login";
import EmptyLayaout from "./layaout/EmptyLayaout";
import AppLayaout from "./layaout/AppLayaout";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import { AuthProvider } from "./hooks/useAuth";
import PrivateRoute from "./pages/PrivateRoute";
import Users from "./pages/Users";
import "react-toastify/dist/ReactToastify.css";
import { ToastContainer } from "react-toastify";
import ViewStoreDetail from "./pages/ViewStoreDetail";
import UpdateStoreDetail from "./pages/UpdateStoreDetail";
import SelectViewStoreDetail from "./pages/SelectViewStoreDetail";
import RegisterFormViewProvider from "./providers/registerFormViewProvider";

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 60 * 1000,
      enabled: false,
    },
  },
});

const router = createBrowserRouter([
  {
    element: <EmptyLayaout />,
    children: [
      {
        path: "/login",
        element: <Login />,
      },
    ],
  },
  {
    element: <AppLayaout />,
    children: [
      {
        path: "/",
        element: (
          <PrivateRoute redirectTo="/login">
            <Homepage />
          </PrivateRoute>
        ),
      },
      {
        path: "/view-store",
        element: (
          <PrivateRoute redirectTo="/login">
            <SelectViewStoreDetail />
          </PrivateRoute>
        ),
      },
      {
        path: "/view-store-detail-resume",
        element: (
          <PrivateRoute redirectTo="/login">
            <ViewStoreDetail />
          </PrivateRoute>
        ),
      },
      {
        path: "/update-store",
        element: (
          <PrivateRoute redirectTo="/login">
            <UpdateStoreDetail />
          </PrivateRoute>
        ),
      },
      {
        path: "/users",
        element: (
          <PrivateRoute redirectTo="/login">
            <Users />
          </PrivateRoute>
        ),
      },
    ],
  },
]);

function App() {
  return (
    <RegisterFormViewProvider>
      <AuthProvider>
        <ToastContainer />
        <QueryClientProvider client={queryClient}>
          <ReactQueryDevtools initialIsOpen={false} position="right" />
          <RouterProvider router={router} />
        </QueryClientProvider>
      </AuthProvider>
    </RegisterFormViewProvider>
  );
}

export default App;

I don't know why it keeps firing the queries if enabled is set to false


Solution

  • Looking at this component, in each useQuery call, you invoke the service function directly within queryFn rather than passing it as a function to be called when the query runs. This approach immediately executes the function on the component mount, ignoring enabled: false.

    Try this and make similar changes to other queries

    const { data: viewDetailStore, isPending: isPendingViewDetailStore } = useQuery({
      queryKey: ["viewStoreDetail"],
      queryFn: () => GetStoreDetailService(
        storedValue,
        state.select_store_id.select_store_id,
      ),
      staleTime: 0,
      enabled: true,
    });