React Query 被设计为可以与 React Native 开箱即用,但开发者工具除外,目前开发者工具仅支持 React DOM。
有一个第三方的 Expo 插件你可以尝试: https://github.com/expo/dev-plugins/tree/main/packages/react-query
有一个第三方的 Flipper 插件你可以尝试: https://github.com/bgaleotti/react-query-native-devtools
有一个第三方的 Reactotron 插件你可以尝试: https://github.com/hsndmr/reactotron-react-query
如果您想帮助我们使内置的开发者工具平台无关,请告诉我们!
React Query 已经支持在 Web 浏览器中重新连接时自动重新获取。要在 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)
})
})
import NetInfo from '@react-native-community/netinfo'
import { onlineManager } from '@tanstack/react-query'
onlineManager.setEventListener((setOnline) => {
return NetInfo.addEventListener((state) => {
setOnline(!!state.isConnected)
})
})
或
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
})
React Native 通过 AppState 模块提供焦点信息,而不是 window 上的事件监听器。您可以使用 AppState "change" 事件在应用程序状态更改为 "active" 时触发更新
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()
}, [])
在某些情况下,您可能希望在 React Native 屏幕再次获得焦点时重新获取查询。当屏幕再次获得焦点时,这个自定义 Hook 将调用提供的 refetch 函数。
import React from 'react'
import { useFocusEffect } from '@react-navigation/native'
export function useRefreshOnFocus<T>(refetch: () => Promise<T>) {
const firstTimeRef = React.useRef(true)
useFocusEffect(
React.useCallback(() => {
if (firstTimeRef.current) {
firstTimeRef.current = false
return
}
refetch()
}, [refetch]),
)
}
import React from 'react'
import { useFocusEffect } from '@react-navigation/native'
export function useRefreshOnFocus<T>(refetch: () => Promise<T>) {
const firstTimeRef = React.useRef(true)
useFocusEffect(
React.useCallback(() => {
if (firstTimeRef.current) {
firstTimeRef.current = false
return
}
refetch()
}, [refetch]),
)
}
在上面的代码中,第一次跳过了 refetch,因为 useFocusEffect 在挂载时以及屏幕聚焦时都会调用我们的回调。
如果您不希望某些查询在屏幕失去焦点时仍然“活动”,您可以使用 useQuery 上的 subscribed 属性。此属性允许您控制查询是否保持订阅更新。与 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>
}
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(例如,当屏幕重新获得焦点时),查询将重新订阅并保持最新状态。