译零 TransZero · TanStack Query 中文文档
主站

React Native

更新于 2026-11-02 React 查看英文原文 ↗

React Query 开箱即用,支持 React Native。

开发者工具(DevTools)支持

React Native 的开发者工具集成有多种可选方案:

  1. Rozenite 插件:面向 React Native DevTools 用户的第三方插件:https://www.rozenite.dev/docs/official-plugins/tanstack-query

  2. 原生 macOS 应用:一款面向任意基于 JavaScript 的应用的 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 在 Web 浏览器中已原生支持网络重连时自动重新拉取(auto refetch on reconnect)。
要在 React Native 中实现相同行为,你需使用 React Query onlineManager,如下例所示:

TypeScript
1import NetInfo from '@react-native-community/netinfo'2import { onlineManager } from '@tanstack/react-query'3 4onlineManager.setEventListener((setOnline) => {5  return NetInfo.addEventListener((state) => {6    setOnline(!!state.isConnected)7  })8})

或

TypeScript
1import { onlineManager } from '@tanstack/react-query'2import * as Network from 'expo-network'3 4onlineManager.setEventListener((setOnline) => {5  let initialized = false6 7  const eventSubscription = Network.addNetworkStateListener((state) => {8    initialized = true9    setOnline(!!state.isConnected)10  })11 12  Network.getNetworkStateAsync()13    .then((state) => {14      if (!initialized) {15        setOnline(!!state.isConnected)16      }17    })18    .catch(() => {19      // getNetworkStateAsync can reject on some platforms/SDK versions20    })21 22  return eventSubscription.remove23})

应用获得焦点时重新拉取

React Native 并不提供对 window 事件监听器的支持,而是通过 AppState 模块 提供应用焦点信息。你可以利用 AppState 的 “change” 事件,在应用状态变为 “active” 时触发更新:

TypeScript
1import { useEffect } from 'react'2import { AppState, Platform } from 'react-native'3import type { AppStateStatus } from 'react-native'4import { focusManager } from '@tanstack/react-query'5 6function onAppStateChange(status: AppStateStatus) {7  if (Platform.OS !== 'web') {8    focusManager.setFocused(status === 'active')9  }10}11 12useEffect(() => {13  const subscription = AppState.addEventListener('change', onAppStateChange)14 15  return () => subscription.remove()16}, [])

屏幕获得焦点时刷新

在某些场景下,你可能希望在 React Native 屏幕再次获得焦点时重新拉取查询。
以下自定义 Hook 可在屏幕再次获得焦点时,重新拉取所有处于活动状态且过期的查询:

TypeScript
1import React from 'react'2import { useFocusEffect } from '@react-navigation/native'3import { useQueryClient } from '@tanstack/react-query'4 5export function useRefreshOnFocus() {6  const queryClient = useQueryClient()7  const firstTimeRef = React.useRef(true)8 9  useFocusEffect(10    React.useCallback(() => {11      if (firstTimeRef.current) {12        firstTimeRef.current = false13        return14      }15 16      // refetch all stale active queries17      queryClient.refetchQueries({18        queryKey: ['posts'],19        stale: true,20        type: 'active',21      })22    }, [queryClient]),23  )24}

上述代码跳过了首次焦点(即屏幕初次挂载时),因为 useFocusEffect 不仅在屏幕获得焦点时调用回调函数,也会在组件挂载时调用。

在屏幕失焦时禁用查询

如果你不希望某些查询在屏幕失焦期间继续保持“活跃”,可以使用 useQuery 的 subscribed 属性。该属性允许你控制查询是否持续订阅更新。结合 React Navigation 的 useIsFocused,你可实现在屏幕失焦时无缝取消查询订阅:

示例用法:

TypeScript
1import React from 'react'2import { useIsFocused } from '@react-navigation/native'3import { useQuery } from '@tanstack/react-query'4import { Text } from 'react-native'5 6function MyComponent() {7  const isFocused = useIsFocused()8 9  const { dataUpdatedAt } = useQuery({10    queryKey: ['key'],11    queryFn: () => fetch(...),12    subscribed: isFocused,13  })14 15  return <Text>DataUpdatedAt: {dataUpdatedAt}</Text>16}

当 subscribed 为 false 时,查询将取消对更新的订阅,不会为此屏幕触发重新渲染,也不会拉取新数据;一旦它再次变为 true(例如屏幕重新获得焦点),查询将重新订阅并保持最新状态。

本页为 TanStack Query 文档(React 版)的非官方中文翻译,原文由上游团队维护,遵循 MIT 许可。 译文如有偏差,以英文原文为准。

译自上游 59d11de