You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Query获取API数据返回undefined问题求助

问题:React Query useQuery返回data始终为undefined

相关代码

自定义API调用中间件apiCaller:

/* eslint-disable @typescript-eslint/no-var-requires */
// /* eslint-disable no-import-assign */
import Axios from 'axios';
import * as queryString from 'query-string';
const caseConverter = require('change-object-case');
import { cleanParams } from '_utilities/common';
import { REQUEST_TYPES } from './constants';
import { useLoginUser } from '_store/user';


interface IAuth {
  method?: string;
  url?: string;
  data?: any;
  params?:any,
  contentType?:string,
  isTransformRequestRequired?:boolean

}

export function apiCaller(
    {
    method = REQUEST_TYPES.GET,
    url = '',
    params = {},
    data = {},
    contentType = 'application/json',
    isTransformRequestRequired = true,
  }:IAuth,
) {
  const user = useLoginUser.getState().user;
  const token = user?.data?.token || ''; 
  // caseConverter.options = {recursive: true, arrayRecursive: true};
  return Axios({
    method,
    url,
    params,
    paramsSerializer: queryParams => queryString.stringify(caseConverter.snakeKeys(cleanParams(queryParams))),
    data,
    transformRequest: [reqData => isTransformRequestRequired
            ? JSON.stringify(caseConverter.toSnake(reqData))
            : reqData],
    transformResponse: [(respData) => 
      { 
         if(typeof respData === 'string')
        return JSON.parse(respData)
        else {
          return respData
        }
      
    }],        
    headers: {
      Authorization: user !== null ? `Token ${ token }` : '',
      'Content-Type': contentType,
    },
    responseType: 'json',
    validateStatus: status => status >= 200 && status < 300,
  })
  .then(({ data: resp }) => resp)
      .catch(error => {
        console.log(error,'error')
        // if user session is expired from server and got 401, will logout the user from application
        if(error.response.status === 401) {
          // store.dispatch(logoutSuccess());
        } else {
          throw(error);
        }
      });
}

调用apiCaller的usersApi:

import { apiCaller } from '../api-caller';
import { ENDPOINTS, REQUEST_TYPES } from '../constants';
import moment from 'moment';
export const usersApi = async (params:any) => { 
  
  const res =  await apiCaller(
  {
    method: REQUEST_TYPES.GET,
    url: `${ENDPOINTS.USERS}/`,
    params:{
      ...params,
      startDatetime: params.startDatetime ? moment(params.startDatetime).utc().format('YYYY-MM-DD H:mm:ss') : '',
      endDatetime: params.endDatetime ?  moment(params.endDatetime).utc().format('YYYY-MM-DD H:mm:ss') : '',
    },
  },
);
return res;
}

封装useQuery的useCreateProfile Hook:

import { useQuery } from '@tanstack/react-query'
import { usersApi } from '_api/users'
import { useAdminUser } from 'pages/Admin/AdminUsers/_store'
const filters = useAdminUser.getState().filters
export const useCreateProfile = () => {
  const query = ['cashierShifts']
  return useQuery(query, () => {
    usersApi(filters)
  })
}

组件中使用Hook:

import React, { useState } from 'react'
import { Table } from 'antd'
import { useCreateProfile } from '_services/CashierProfile'

const columns = [
  {
    title: 'Day',
    dataIndex: 'day',
    key: 'day',
  },
  {
    title: 'Shift',
    dataIndex: 'shift',
    key: 'shift',
  },
  {
    title: 'startTime',
    dataIndex: 'start',
    key: 'start',
  },
  {
    title: 'endTime',
    dataIndex: 'end',
    key: 'end',
  },
  {
    title: 'Mart',
    dataIndex: 'mart',
    key: 'mart',
  },
]

const CashierShifts = () => {
  const { data, isError, isLoading, isSuccess } = useCreateProfile()
  console.log(data, 'react-query')
  const [result, setResult] = useState([
    {
      id: 54,
      tile: 'slots 1',
      date: '22-10-2203',
      startTime: '8:00',
      mart: {
        id: 21,
        martName: 'Johar Town',
      },
      endTime: '12:00',
      cashier: {
        name: 'Jamal',
        id: 54,
      },
    },
    {
      id: 54,
      tile: 'slots 1',
      date: '22-10-2203',
      startTime: '8:00',
      mart: {
        id: 21,
        martName: 'Johar Town',
      },
      endTime: '12:00',
      cashier: {
        name: 'Jamal',
        id: 54,
      },
    },
    {
      id: 54,
      tile: 'slots 1',
      date: '22-10-2203',
      startTime: '8:00',
      mart: {
        id: 21,
        martName: 'Johar Town',
      },
      endTime: '12:00',
      cashier: {
        name: 'Jamal',
        id: 54,
      },
    },
    {
      id: 54,
      tile: 'slots 1',
      date: '22-10-2203',
      startTime: '8:00',
      mart: {
        id: 21,
        martName: 'Johar Town',
      },
      endTime: '12:00',
      cashier: {
        name: 'Jamal',
        id: 54,
      },
    },
  ])
  const dataSource = result.map((a) => ({
    day: a.date,
    shift: a.tile,
    start: a.startTime,
    end: a.endTime,
    mart: a.mart.martName,
  }))

  return (
    <div>
      <Table columns={columns} dataSource={dataSource} />
    </div>
  )
}

export default CashierShifts

问题排查与修复

核心原因1:useQuery查询函数未返回Promise

在useCreateProfile中,useQuery的第二个箭头函数调用usersApi(filters)后未返回该Promise,导致React Query无法捕获异步请求结果,最终data始终为undefined。

核心原因2:filters获取时机错误

在Hook外部直接读取filters,只会在Hook初始化时获取一次值,后续store中filters变化时不会触发useQuery重新查询,还可能传递未初始化的参数给接口。

修复方案

修改useCreateProfile Hook,确保返回Promise并正确处理依赖参数:

import { useQuery } from '@tanstack/react-query'
import { usersApi } from '_api/users'
import { useAdminUser } from 'pages/Admin/AdminUsers/_store'

export const useCreateProfile = () => {
  // 在Hook内部获取最新的filters
  const filters = useAdminUser.getState().filters
  // 将filters加入queryKey,参数变化时自动触发重新查询
  const queryKey = ['cashierShifts', filters]

  return useQuery(queryKey, () => {
    // 返回usersApi的Promise,让React Query处理异步结果
    return usersApi(filters)
  })
}

额外优化:添加错误处理

在组件中添加错误状态捕获,方便排查请求失败的情况:

const CashierShifts = () => {
  const { data, isError, isLoading, isSuccess, error } = useCreateProfile()
  
  // 打印错误信息辅助排查
  if (isError) {
    console.error('请求失败:', error)
  }
  
  console.log(data, 'react-query')
  // ... 其他组件代码
}

验证要点

  • 单独调用usersApi确认能正常返回后端数据
  • 检查浏览器Network面板,确认接口请求是否成功、响应数据是否正确
  • 确保React Query的Provider已正确包裹应用根组件

内容的提问来源于stack exchange,提问作者Asad Ur Rehman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 05:10:21