React Query ist darauf ausgelegt, sofort mit React Native zu funktionieren.
Es gibt verschiedene Optionen für die Integration von React Native DevTools
Native macOS App: Eine Drittanbieter-App zum Debuggen von React Query in jeder JS-basierten Anwendung: https://github.com/LovesWorking/rn-better-dev-tools
Flipper Plugin: Ein Drittanbieter-Plugin für Flipper-Benutzer: https://github.com/bgaleotti/react-query-native-devtools
Reactotron Plugin: Ein Drittanbieter-Plugin für Reactotron-Benutzer: https://github.com/hsndmr/reactotron-react-query
React Query unterstützt bereits das automatische erneute Abrufen nach Wiederverbindung im Webbrowser. Um dieses Verhalten in React Native hinzuzufügen, müssen Sie den onlineManager von React Query wie im folgenden Beispiel verwenden
import NetInfo from '@react-native-community/netinfo'
import { onlineManager } from '@tanstack/react-query'
onlineManager.setEventListener((setOnline) => {
return NetInfo.addEventListener((state) => {
setOnline(!!state.isConnected)
})
})
import NetInfo from '@react-native-community/netinfo'
import { onlineManager } from '@tanstack/react-query'
onlineManager.setEventListener((setOnline) => {
return NetInfo.addEventListener((state) => {
setOnline(!!state.isConnected)
})
})
oder
import { onlineManager } from '@tanstack/react-query'
import * as Network from 'expo-network'
onlineManager.setEventListener((setOnline) => {
const eventSubscription = Network.addNetworkStateListener((state) => {
setOnline(!!state.isConnected)
})
return eventSubscription.remove
})
import { onlineManager } from '@tanstack/react-query'
import * as Network from 'expo-network'
onlineManager.setEventListener((setOnline) => {
const eventSubscription = Network.addNetworkStateListener((state) => {
setOnline(!!state.isConnected)
})
return eventSubscription.remove
})
Anstelle von Ereignis-Listenern auf window liefert React Native Fokusinformationen über das AppState-Modul. Sie können das AppState "change"-Ereignis verwenden, um ein Update auszulösen, wenn sich der App-Status zu "aktiv" ändert.
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()
}, [])
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()
}, [])
In einigen Situationen möchten Sie die Abfrage möglicherweise erneut abrufen, wenn ein React Native Screen wieder in den Fokus gerät. Dieser benutzerdefinierte Hook ruft alle aktiven veralteten Abfragen erneut ab, wenn der Bildschirm erneut in den Fokus gerät.
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]),
)
}
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]),
)
}
Im obigen Code wird der erste Fokus (wenn der Bildschirm zunächst gemountet wird) übersprungen, da useFocusEffect unseren Callback zusätzlich zum Bildschirmfokus beim Mounten aufruft.
Wenn Sie nicht möchten, dass bestimmte Abfragen "live" bleiben, während sich ein Bildschirm ausserhalb des Fokus befindet, können Sie die "subscribed"-Prop auf "useQuery" verwenden. Diese Prop ermöglicht es Ihnen zu steuern, ob eine Abfrage mit Updates abonniert bleibt. In Kombination mit "useIsFocused" von React Navigation können Sie Abfragen nahtlos abbestellen, wenn ein Bildschirm nicht im Fokus ist.
Beispielanwendung
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>
}
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>
}
Wenn "subscribed" false ist, wird die Abfrage von Updates abbestellt und löst keine erneuten Renderings aus oder ruft keine neuen Daten für diesen Bildschirm ab. Sobald sie wieder true wird (z.B. wenn der Bildschirm wieder in den Fokus gerät), wird die Abfrage erneut abonniert und bleibt auf dem neuesten Stand.