공식문서 : https://tanstack.com/query/v4/docs/guides/window-focus-refetching
유저가 애플리케이션을 떠나고 stale한 데이터로 돌아오면, React Query는 백그라운드에서 자동으로 fresh 데이터를 요청한다. refetchOnWindowFocus
옵션을 사용하여 이 기능을 전역적으로 또는 쿼리별로 비활성화할 수 있다.
//
const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
},
},
})
function App() {
return <QueryClientProvider client={queryClient}>...</QueryClientProvider>
}
useQuery(['todos'], fetchTodos, { refetchOnWindowFocus: false })
드문 경우이지만, revalidate를 위해 React Query를 트리거하는 자체 window focus event를 관리하고 싶을 수 있다. 이를 위해, React Query는 window가 focus되었을때 호출되어야하는 콜백을 제공하고 고유한 event를 설정할 수 있는focusManager.setEventListener
함수를 제공한다. focusManager.setEventListener
를 호출하면, 이전에 설정된 handler는 제거되고(대부분의 경우 default handler가 됨) 새 handler가 대신 사용된다. 예를들어, 다음은 default handler이다 :
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)
}
})
focus handler를 교체하는 좋은 사용사례는 iframe event이다. Iframe은 앱 내에서 focus를 맞추거나 iframe을 사용할 때 이중 실행 이벤트와 false-positive 이벤트를 모두 실행하여 window focus를 감지하는데 문제가 있다. 이러한 현상이 발생하면, 이러한 이벤트들을 최대한 무시하는 이벤트 핸들러를 사용해야한다. 나는 이것을 추천한다! 다음과 같은 방법으로 설정할 수 있다 :
import { focusManager } from '@tanstack/react-query'
import onWindowFocus from './onWindowFocus' // The gist above
focusManager.setEventListener(onWindowFocus) // Boom!
window
의 이벤트 핸들러 대신, React Native는 AppState
모듈을 통해 focus 정보를 제공한다. AppState
'change' 이벤트를 사용하여 앱 상태가 'active'로 바뀔때 업데이트를 트리거할 수 있다.
import { AppState } from 'react-native'
import { focusManager } from '@tanstack/react-query'
focusManager.setEventListener(handleFocus => {
const subscription = AppState.addEventListener('change', state => {
handleFocus(state === 'active')
})
return () => {
subscription.remove()
}
})
import { focusManager } from '@tanstack/react-query'
// Override the default focus state
focusManager.setFocused(true)
// Fallback to the default focus check
focusManager.setFocused(undefined)
alert()
에 의해 생성되거나 파일 업로드 대화상자(<input type="file"/>
에 의해 생성된)와 같은 일부 브라우저 내부 대화창도 닫힌 후 focus refetching을 트리거할 수도 있다. 파일 업로드 핸들러가 실행되기 전에 refecthing이 컴포넌트 unmount 또는 remount를 트리거할 수 있으므로 원치않는 부작용이 발생할 수 있다. 백그라운드 및 가능한 해결 방법은 Github의 issue를 참고하라.