React Query:当Query处于isStale状态时如何触发重新获取?
React Query 失效数据切换视图后未重新获取的解决方案
场景与代码
视图X:展示用户活动数据
export type UseIntegrationsProps = GetIntegrationRequest & { enabled: boolean; }; export const useIntegrations = ({ order, filters, enabled, }: UseIntegrationsProps) => { return useQuery<Integration[]>({ queryFn: () => getIntegrations({ order, filters }), queryKey: commonQueriesFactory.integrations.item(filters, order), }); };
视图Y:添加新活动并失效数据
type UsePostActivityProps = { id: string | undefined; }; export const usePostActivity = ({ substreamId, }: UsePostActivityProps) => { const queryClient = useQueryClient(); const { onErrorToast } = useToastNotification(); const { mutateAsync: addActivityMutation, isLoading } = useMutation({ mutationFn: addActivity, }); const onActivityPost = async (text: string) => { try { await addActivityMutation({ id, text }); // 失效相关查询 queryClient.invalidateQueries(substreamQueriesFactory.activities.all(id)); } catch (e) { onErrorToast('Oops! Something went wrong, failed to post activity. Try again.'); } }; return { onActivityPost, isLoading }; };
问题
从视图Y切换回视图X时,尽管目标query的isStale为true,但未触发重新获取数据。使用refetchType: 'all'会立即获取,但会导致非活跃状态下也触发请求,不符合需求。需要实现:仅当query处于失效状态且用户切换回视图X时,触发重新获取。
解决方案
1. 确保QueryKey匹配(核心前提)
你当前在视图Y中失效的substreamQueriesFactory.activities.all(id)与视图X的commonQueriesFactory.integrations.item(filters, order)是不同的QueryKey,导致视图X的query未被标记为失效。请:
- 统一两个视图的QueryKey,确保
invalidateQueries能精准匹配到目标query; - 或使用前缀匹配,比如如果视图X的QueryKey前缀是
['activities', id],则失效时用:queryClient.invalidateQueries({ queryKey: ['activities', id] });
2. 利用refetchOnMount配置
React Query默认refetchOnMount: true,即组件挂载时若数据失效(stale)会自动重新获取。可在视图X的useQuery中明确配置(确保未被全局配置覆盖):
export const useIntegrations = ({ order, filters, enabled, }: UseIntegrationsProps) => { return useQuery<Integration[]>({ queryFn: () => getIntegrations({ order, filters }), queryKey: commonQueriesFactory.integrations.item(filters, order), refetchOnMount: true, // 明确开启,确保失效数据在组件挂载时重新获取 }); };
3. 手动触发Refetch(兜底方案)
若自动配置不生效,可在视图X的组件中,通过useEffect监听失效状态,手动触发重新获取:
const { isStale, refetch } = useIntegrations({ /* 你的参数 */ }); useEffect(() => { // 组件挂载且数据失效时,手动触发重新获取 if (isStale) { refetch(); } }, [isStale, refetch]);
内容的提问来源于stack exchange,提问作者qwerty1234567
相关产品推荐
相关产品推荐

