T
TanStack11mo ago
vicious-gold

refetchOnWindowFocus seems to be getting ignored sometimes

Hi all! I am having an issue with my tanstack query useQuery hook. This is for a fully client-side SPA app, in Typescript React with Vite under the hood. I have a file where I lay out all of the queries with the query options; the one in question:
export const camps = (getToken: GetToken) => ({
get: (id?: string) =>
queryOptions<CampEvent>({
queryKey: ["camp", id],
queryFn: async () => {
// biome-ignore lint/style/noNonNullAssertion: checked by enabled
const { url, method } = API_ROUTES.GET_CAMP(id!);
const response = await customFetch(getToken, url, { method });
if (!response.ok) throw new Error("Failed to fetch camp");
return response.json();
},
enabled: !!id && id !== "new",
}),
export const camps = (getToken: GetToken) => ({
get: (id?: string) =>
queryOptions<CampEvent>({
queryKey: ["camp", id],
queryFn: async () => {
// biome-ignore lint/style/noNonNullAssertion: checked by enabled
const { url, method } = API_ROUTES.GET_CAMP(id!);
const response = await customFetch(getToken, url, { method });
if (!response.ok) throw new Error("Failed to fetch camp");
return response.json();
},
enabled: !!id && id !== "new",
}),
And on the Create/Edit page, this is how said hook is used, for the scenario to load the data into the form:
// Query existing camp if editing
const campQuery = useQuery({
...camps(getToken).get(id),
select: (data) => {
// omitted for brevity
},
refetchOnWindowFocus: false,
staleTime: Number.POSITIVE_INFINITY,
});

const form = useForm<CampCreateForm>({
resolver: zodResolver(campCreateForm),
mode: "all",
defaultValues: {
admin_share: 35,
teaching_teams: [],
session_timings: [],
class_assignments: [],
},
values: id && id !== "new" ? campQuery.data : undefined,
});
// Query existing camp if editing
const campQuery = useQuery({
...camps(getToken).get(id),
select: (data) => {
// omitted for brevity
},
refetchOnWindowFocus: false,
staleTime: Number.POSITIVE_INFINITY,
});

const form = useForm<CampCreateForm>({
resolver: zodResolver(campCreateForm),
mode: "all",
defaultValues: {
admin_share: 35,
teaching_teams: [],
session_timings: [],
class_assignments: [],
},
values: id && id !== "new" ? campQuery.data : undefined,
});
The issue with this is that the refetchOnWindowFocus option seems to sometimes be ignored. In the screen recording you will see a video of me clicking back and forth changing the focus, and about 1 in every 4 clicks it refetches the data and resets the form. this could be an issue as the user would lose their data if they needed to click away in the form. I tried to create a minimal reproduction but was unable to.
7 Replies
ambitious-aqua
ambitious-aqua11mo ago
clicking in and out of the chrome devtools does not trigger a window focus refetch anymore since v5
ambitious-aqua
ambitious-aqua11mo ago
Window Focus Refetching | TanStack Query React Docs
If a user leaves your application and returns and the query data is stale, TanStack Query automatically requests fresh data for you in the background. You can disable this globally or per-query using...
ambitious-aqua
ambitious-aqua11mo ago
Migrating to TanStack Query v5 | TanStack Query React Docs
Breaking Changes v5 is a major version, so there are some breaking changes to be aware of: Supports a single signature, one object useQuery and friends used to have many overloads in TypeScript differ...
vicious-gold
vicious-goldOP11mo ago
im not clicking in out of devtools, in the video i click back and forth between vs code and the active browser area. why does this still occassionally trigger data refetch?
ambitious-aqua
ambitious-aqua11mo ago
Because that also doesn't trigger a visibilitychange event
flat-fuchsia
flat-fuchsia11mo ago
Every time you click in and out you have 3 requests firing in your video. Which of those 3 is related to the url in the react query hook API_ROUTES.GET_CAMP(id!)? And what do the others do? Just seems like something else could be causing the rerender
vicious-gold
vicious-goldOP11mo ago
it's the one with the uuid. the first is from the auth provider, clerk. the other one is a useinfinitequery to fill a combobox with options.

Did you find this page helpful?