React Typescript使用React Query调用接口时每次点击页面重复触发请求如何解决
问题根因与解决方案
你代码中实际使用的是 React Query 提供的useQuery(用于数据查询),并非mutation(用于增删改类操作),出现点击页面重复调用接口、卡顿的问题有两个核心原因:
- React Query 默认开启了
refetchOnWindowFocus配置,页面被点击聚焦时会自动触发数据重取 - 你的加载逻辑判断只要
isLoading为真就返回全屏加载页,重取过程中原有已加载内容会被替换,表现为卡顿、状态丢失
具体修复步骤
1. 关闭不必要的自动重取配置
修改useGetFromApi中useQuery的调用参数,显式关闭窗口聚焦重取,还可根据业务需要配置数据过期时间,避免无意义的重取:
export function useGetFromApi(url: string, parameters: string[]) { const { getAccessToken } = usePidgetIdentity(); let apiUrl: string = config.FORMS_API_URL + '/' + url; parameters.map((parameter) => { apiUrl += '/' + parameter.trim(); }); console.log('Calling ' + apiUrl); return useQuery<ApiData, Error>(apiUrl, () => callToApi(apiUrl, getAccessToken), { refetchOnWindowFocus: false, // 核心配置:关闭页面聚焦自动重取 staleTime: Infinity, // 可选:标记查询到的数据永不过期,只要有缓存就不会自动触发重取 refetchOnMount: false, // 可选:组件二次挂载时如果有缓存,不自动重取 refetchOnReconnect: false // 可选:网络恢复时不自动重取 }); }
2. 优化加载状态判断逻辑
isLoading仅在首次无缓存加载时为真,后续重取时只会触发isFetching状态变更,调整加载逻辑,避免重取时替换原有页面内容:
export const Instances = (props: InstanceProps) => { const history = useHistory<{ formId: number; rowData: any; formInstanceID: number; }>(); // 多解构出isFetching用于重取状态提示 const { isLoading, isFetching, isError, isSuccess, data, error } = useGetFromApi('api/list', [ `${history.location.state.formId}`, ]); // 只有首次无数据加载时才展示全屏加载页 if (isLoading && !data) { return ( <div> Page Loading </div> ); } if (isError) { return ( <div> An error occurred </div> ); } if (isSuccess) { if (data) { // Map data to an array for the table component } } return ( <div> {/* 重取时仅展示轻量提示,不影响原有内容 */} {isFetching && <div style={{position: 'fixed', top: 0, left: 0, right: 0, height: '2px', background: 'blue'}} />} Display table showing data </div> ); };
3. 兜底校验点
如果修改完上述配置仍有重复请求,可检查上层组件是否在点击按钮时触发了状态更新,导致Instances组件被卸载后重新挂载,触发重复的初始化查询。
内容的提问来源于stack exchange,提问作者dickiebow
相关产品推荐
相关产品推荐

