[TanStakQuery] Window Focus Refetching

Jeris·2023년 5월 22일
0

사용자가 애플리케이션을 떠났다가 다시 돌아와서 쿼리 데이터가 오래된 경우, TanStack Query는 백그라운드에서 자동으로 새로운 데이터를 요청합니다. 이 기능을 전역 또는 쿼리별로 비활성화할 수 있으며, refetchOnWindowFocus 옵션을 사용하면 됩니다:

Disabling Globally

//
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      refetchOnWindowFocus: false, // default: true
    },
  },
})

function App() {
  return <QueryClientProvider client={queryClient}>...</QueryClientProvider>
}

Disabling Per-Query

useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodos,
  refetchOnWindowFocus: false,
})

Custom Window Focus Event

드문 경우지만, TanStack Query가 재검증하도록 트리거하는 own window focus events를 관리하고 싶을 수도 있습니다. 이를 위해 TanStack Query는 창에 포커스가 맞춰졌을 때 실행해야 하는 콜백을 제공하고 사용자가 직접 이벤트를 설정할 수 있도록 하는 focusManager.setEventListener 함수를 제공합니다. focusManager.setEventListener를 호출하면 이전에 설정된 핸들러가 제거되고(대부분의 경우 기본 핸들러) 대신 새 핸들러가 사용됩니다. 예를 들어, 이것이 기본 핸들러입니다:

focusManager.setEventListener((handleFocus) => {
  // Listen to visibilitychange and focus
  if (typeof window !== 'undefined' && window.addEventListener) {
    window.addEventListener('visibilitychange', handleFocus, false)
    window.addEventListener('focus', handleFocus, false)
  }

  return () => {
    // Be sure to unsubscribe if a new handler is set
    window.removeEventListener('visibilitychange', handleFocus)
    window.removeEventListener('focus', handleFocus)
  }
})

아이프레임에서 포커스 이벤트 무시하기(Ignoring Iframe Focus Events)

포커스 핸들러를 대체할 수 있는 좋은 사용 사례는 iframe 이벤트입니다. 아이프레임은 앱 내에서 포커스를 맞추거나 아이프레임을 사용할 때 double-firing 이벤트를 발생시키고 false-positive 이벤트를 발생시키기 때문에 창 포커스를 감지하는 데 문제가 있습니다. 이 문제가 발생하면 가능한 한 이러한 이벤트를 무시하는 이벤트 핸들러를 사용해야 합니다. 저는 이것을 추천합니다! 다음과 같은 방법으로 설정할 수 있습니다:

import { focusManager } from '@tanstack/react-query'
import onWindowFocus from './onWindowFocus' // The gist above

focusManager.setEventListener(onWindowFocus) // Boom!

React Native에서 포커스 다루기(Managing Focus in React Native)

window에 있는 이벤트 리스너 대신 React Native는 AppState module을 통해 포커스 정보를 제공합니다. 앱 상태가 "active"로 변경될 때 AppState "change" 이벤트를 사용하여 업데이트를 트리거할 수 있습니다:

import { AppState } from 'react-native'
import { focusManager } from '@tanstack/react-query'

function onAppStateChange(status: AppStateStatus) {
  if (Platform.OS !== 'web') {
    focusManager.setFocused(status === 'active')
  }
}

useEffect(() => {
  const subscription = AppState.addEventListener('change', onAppStateChange)

  return () => subscription.remove()
}, [])

포커스 상태 다루기(Managing focus state)

import { focusManager } from '@tanstack/react-query'

// Override the default focus state
focusManager.setFocused(true)

// Fallback to the default focus check
focusManager.setFocused(undefined)

함정과 주의 사항(Pitfalls & Caveats)

alert()에 의해 생성되는 일부 브라우저 내부 대화창이나 파일 업로드 대화창(<input type="file" />에 의해 생성됨)은 닫힌 후에도 포커스 리페칭을 트리거할 수 있습니다. 이로 인해 파일 업로드 핸들러가 실행되기 전에 컴포넌트 마운트 해제 또는 재마운트가 트리거될 수 있으므로 원치 않는 side effects가 발생할 수 있습니다. 해결 방법은 this issue on GitHub에서 이 문제를 참조하세요.

Reference

profile
job's done

0개의 댓글