Framework
Version

React Native

React Query ist darauf ausgelegt, sofort mit React Native zu funktionieren.

DevTools Unterstützung

Es gibt verschiedene Optionen für die Integration von React Native DevTools

  1. Native macOS App: Eine Drittanbieter-App zum Debuggen von React Query in jeder JS-basierten Anwendung: https://github.com/LovesWorking/rn-better-dev-tools

  2. Flipper Plugin: Ein Drittanbieter-Plugin für Flipper-Benutzer: https://github.com/bgaleotti/react-query-native-devtools

  3. Reactotron Plugin: Ein Drittanbieter-Plugin für Reactotron-Benutzer: https://github.com/hsndmr/reactotron-react-query

Online-Statusverwaltung

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

tsx
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

tsx
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
})

Neu laden bei App-Fokus

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.

tsx
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()
}, [])

Neu laden bei Bildschirmfokus

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.

tsx
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.

Abfragen bei ausserhalb des Fokus liegenden Bildschirmen deaktivieren

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

tsx
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.