Window Focus Refetching

· abundance's blog


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 the refetchOnWindowFocus option:

Disabling Globally #

 1//
 2const queryClient = new QueryClient({
 3  defaultOptions: {
 4    queries: {
 5      refetchOnWindowFocus: false, // default: true
 6    },
 7  },
 8})
 9
10function App() {
11  return <QueryClientProvider client={queryClient}>...</QueryClientProvider>
12}

Disabling Per-Query #

1useQuery({
2  queryKey: ['todos'],
3  queryFn: fetchTodos,
4  refetchOnWindowFocus: false,
5})

Custom Window Focus Event #

In rare circumstances, you may want to manage your own window focus events that trigger TanStack Query to revalidate. To do this, TanStack Query provides a focusManager.setEventListener function that supplies you the callback that should be fired when the window is focused and allows you to set up your own events. When calling focusManager.setEventListener, the previously set handler is removed (which in most cases will be the default handler) and your new handler is used instead. For example, this is the default handler:

 1focusManager.setEventListener((handleFocus) => {
 2  // Listen to visibilitychange
 3  if (typeof window !== 'undefined' && window.addEventListener) {
 4    const visibilitychangeHandler = () => {
 5      handleFocus(document.visibilityState === 'visible')
 6    }
 7    window.addEventListener('visibilitychange', visibilitychangeHandler, false)
 8    return () => {
 9      // Be sure to unsubscribe if a new handler is set
10      window.removeEventListener('visibilitychange', visibilitychangeHandler)
11    }
12  }
13})

Managing Focus in React Native #

Instead of event listeners on window, React Native provides focus information through the AppState module. You can use the AppState "change" event to trigger an update when the app state changes to "active":

 1import { AppState } from 'react-native'
 2import { focusManager } from '@tanstack/react-query'
 3
 4function onAppStateChange(status: AppStateStatus) {
 5  if (Platform.OS !== 'web') {
 6    focusManager.setFocused(status === 'active')
 7  }
 8}
 9
10useEffect(() => {
11  const subscription = AppState.addEventListener('change', onAppStateChange)
12
13  return () => subscription.remove()
14}, [])

Managing focus state #

1import { focusManager } from '@tanstack/react-query'
2
3// Override the default focus state
4focusManager.setFocused(true)
5
6// Fallback to the default focus check
7focusManager.setFocused(undefined)