在React Native中使用@tanstack/react-query时refetchOnWindowFocus不生效
React Native中@tanstack/react-query refetchOnWindowFocus不生效的解决办法
核心原因
React Native 不存在浏览器环境的 window 对象,而 @tanstack/react-query 默认的 refetchOnWindowFocus 逻辑依赖浏览器的 focus/blur 事件触发,所以直接设置这个参数在 RN 场景下不会生效。
解决方案
根据你的场景(应用前后台切换/应用内屏幕切换),可以选择以下两种方案:
1. 监听AppState处理应用前后台切换
利用 React Native 原生的 AppState API 监听应用从后台回到前台的事件,手动触发查询重取:
import { QueryClient } from '@tanstack/react-query'; import { AppState } from 'react-native'; // 初始化QueryClient时关闭默认的浏览器focus监听 const queryClient = new QueryClient({ defaultOptions: { queries: { refetchOnWindowFocus: false, }, }, }); // 添加AppState监听 AppState.addEventListener('change', (nextState) => { if (nextState === 'active') { // 应用回到前台时,重取所有活跃状态的查询 queryClient.refetchQueries({ active: true }); // 若只想重取特定查询,可指定queryKey: // queryClient.refetchQueries(['user-profile', 'product-list']); } });
2. 结合导航事件处理应用内屏幕切换
如果是同一应用内切换屏幕(比如使用 react-navigation),AppState 不会触发变化,这时需要监听屏幕的 focus 事件:
import { useFocusEffect } from '@react-navigation/native'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import React from 'react'; import { View, Text } from 'react-native'; function TargetScreen() { const queryClient = useQueryClient(); // 监听屏幕获得焦点事件 useFocusEffect( React.useCallback(() => { // 重取当前屏幕对应的查询 queryClient.refetchQueries(['target-data']); }, [queryClient]) ); // 定义查询,关闭默认的refetchOnWindowFocus const { data, isLoading } = useQuery({ queryKey: ['target-data'], queryFn: () => fetch('/api/target-data'), refetchOnWindowFocus: false, }); if (isLoading) return <Text>加载中...</Text>; return <View><Text>{data?.content}</Text></View>; } export default TargetScreen;
额外检查点
- 确认单个查询的
refetchOnWindowFocus配置没有覆盖全局默认值(单个查询的配置优先级更高); - 确保
QueryClient实例通过QueryClientProvider正确注入到应用根组件,整个应用使用同一个实例。
内容的提问来源于stack exchange,提问作者raphyabak
相关产品推荐
相关产品推荐

