본문으로 건너뛰기

React Native

React Query는 별도 설정 없이 React Native와 함께 작동하도록 설계되었습니다.

DevTools 지원

React Native DevTools 통합에 사용할 수 있는 몇 가지 옵션이 있습니다:

  1. Rozenite Plugin: React Native DevTools 사용자를 위한 서드 파티 플러그인: https://www.rozenite.dev/docs/official-plugins/tanstack-query

  2. 네이티브 macOS 앱: 모든 js 기반 애플리케이션에서 React Query를 디버깅하기 위한 서드 파티 앱입니다: https://github.com/LovesWorking/rn-better-dev-tools

  3. Flipper 플러그인: Flipper 사용자를 위한 서드 파티 플러그인: https://github.com/bgaleotti/react-query-native-devtools

  4. Reactotron 플러그인: Reactotron 사용자를 위한 서드 파티 플러그인: https://github.com/hsndmr/reactotron-react-query

온라인 상태 관리

React Query는 이미 웹 브라우저에서 재연결 시 자동 다시 가져오기를 지원합니다. React Native에 이 동작을 추가하려면 아래 예시와 같이 React Query onlineManager를 사용해야 합니다:

import NetInfo from '@react-native-community/netinfo'
import { onlineManager } from '@tanstack/react-query'

onlineManager.setEventListener((setOnline) => {
return NetInfo.addEventListener((state) => {
setOnline(!!state.isConnected)
})
})

or

import { onlineManager } from '@tanstack/react-query'
import * as Network from 'expo-network'

onlineManager.setEventListener((setOnline) => {
let initialised = false

const eventSubscription = Network.addNetworkStateListener((state) => {
initialised = true
setOnline(!!state.isConnected)
})

Network.getNetworkStateAsync()
.then((state) => {
if (!initialised) {
setOnline(!!state.isConnected)
}
})
.catch(() => {
// getNetworkStateAsync can reject on some platforms/SDK versions
})

return eventSubscription.remove
})

앱 포커스 시 다시 가져오기

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

import { useEffect } from 'react'
import { AppState, Platform } from 'react-native'
import type { AppStateStatus } 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()
}, [])

화면 포커스 시 새로고침

일부 상황에서는 React Native Screen에 다시 포커스될 때 쿼리를 다시 가져오고 싶을 수 있습니다. 이 사용자 지정 훅은 화면에 다시 포커스가 맞춰지면 활성 상태인 모든 stale 상태의 쿼리를 다시 가져옵니다.

import React from 'react'
import { useFocusEffect } from '@react-navigation/native'
import { useQueryClient } from '@tanstack/react-query'

export function useRefreshOnFocus() {
const queryClient = useQueryClient()
const firstTimeRef = React.useRef(true)

useFocusEffect(
React.useCallback(() => {
if (firstTimeRef.current) {
firstTimeRef.current = false
return
}

// refetch all stale active queries
queryClient.refetchQueries({
queryKey: ['posts'],
stale: true,
type: 'active',
})
}, [queryClient]),
)
}

위 코드에서는 useFocusEffect가 화면 포커스 시뿐 아니라 마운트할 때도 콜백을 호출하므로 첫 번째 포커스(화면이 처음 마운트될 때)를 건너뜁니다.

포커스를 벗어난 화면에서 쿼리 비활성화

화면에 포커스가 없는 동안 특정 쿼리를 “활성” 상태로 유지하고 싶지 않다면 useQuery의 subscribed prop을 사용할 수 있습니다. 이 prop을 사용하면 쿼리가 업데이트를 계속 구독할지 제어할 수 있습니다. React Navigation의 useIsFocused와 함께 사용하면 화면에 포커스가 없을 때 쿼리 구독을 원활하게 해제할 수 있습니다:

사용 예제:

import React from 'react'
import { useIsFocused } from '@react-navigation/native'
import { useQuery } from '@tanstack/react-query'
import { Text } from 'react-native'

function MyComponent() {
const isFocused = useIsFocused()

const { dataUpdatedAt } = useQuery({
queryKey: ['key'],
queryFn: () => fetch(...),
subscribed: isFocused,
})

return <Text>DataUpdatedAt: {dataUpdatedAt}</Text>
}

subscribed가 false이면 쿼리는 업데이트 구독을 해제하며 해당 화면에서 다시 렌더링하거나 새 데이터를 가져오지 않습니다. 다시 true가 되면(예: 화면이 포커스를 되찾을 때) 쿼리는 다시 구독하여 최신 상태를 유지합니다.