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

React Query获取后端数据但data.results为undefined求助

问题描述

我是React和TypeScript新手,刚完成相关课程。课程里能正常访问数据,但自己的项目里数据展示不出来。React Query已成功从后端获取数据(React Query DevTools能看到响应结果),但尝试映射data.results时发现它是undefined。

service/apiClient.ts(服务层)

import axios, {AxiosRequestConfig} from "axios";

export interface FetchResponse<T> {
    count: number;
    results: T[];
}

const axiosInstance = axios.create({
    baseURL: 'http://127.0.0.1:8000/api',
})

class APIClient<T>{
    endpoint: string;

    constructor(endpoint: string){ 
        this.endpoint = endpoint;
    }

    getAll = (config: AxiosRequestConfig) => {
        return axiosInstance
        .get<FetchResponse<T>>(this.endpoint, config)
        .then(res=>res.data)
    }

    get = (id: number | string) => {
        return axiosInstance
        .get<T>(this.endpoint + '/' + id )
        .then(res => res.data)
    }
}

export default APIClient

hooks/useMaterials.ts(自定义Hook)

import { useQuery } from "@tanstack/react-query";
import ms from 'ms';
import Material from "../entities/Material";
import APIClient from "../services/apiClient";

const apiClient = new APIClient<Material>('/materials')

const useMaterials = () =>
    useQuery({
        queryKey: ['materials'],
        queryFn: apiClient.getAll,
        staleTime: ms('1m')
    })

export default useMaterials

components/MaterialList.tsx(组件)

import {
  Spinner,
  Table,
  TableContainer,
  Tbody,
  Td,
  Th,
  Thead,
  Tr,
} from "@chakra-ui/react";
import useMaterials from "../hooks/useMaterials";

const MaterialList = () => {
  const { data, isLoading, error } = useMaterials();

  if (error) return null;
  if (isLoading) return <Spinner />;

  return (
    <>
      <TableContainer>
        <Table variant="striped" colorScheme="#E43D12">
          <Thead>
            <Tr>
              <Th>Title</Th>
              <Th>Qty</Th>
              <Th>Action</Th>
            </Tr>
          </Thead>
          <Tbody>
            {data?.results?.map((material) => (
              <Tr key={material.id}>
                <Td>{material.title}</Td>
                <Td>{material.qty}</Td>
                <Td></Td>
              </Tr>
            ))}
          </Tbody>
        </Table>
      </TableContainer>
    </>
  );
};

export default MaterialList;

entities/Material.ts(接口定义)

export default interface Material {
    id: number;
    title: string;
    slug: string;
    qty: number;
}

相关数据说明

  1. React Query DevTools响应结果:返回的是纯物料数组,而非{count: number; results: T[]}结构
  2. data控制台日志:输出为包含多个物料对象的数组,每个对象包含id、title、slug、qty属性
  3. data?.results控制台日志:输出为undefined,因为data本身就是数组,不存在results属性
解决方案

核心问题是你定义的FetchResponse<T>结构和后端实际返回的数据格式不匹配,后端直接返回了物料数组,而非带results字段的对象。

1. 修改API客户端的getAll方法

调整类型定义,匹配后端返回的数组格式:

// service/apiClient.ts
getAll = (config: AxiosRequestConfig) => {
    return axiosInstance
    .get<T[]>(this.endpoint, config) // 直接指定返回T类型数组
    .then(res=>res.data)
}

2. 更新组件中的数据遍历逻辑

因为data现在是数组,直接遍历即可:

// components/MaterialList.tsx
<Tbody>
  {data?.map((material) => (
    <Tr key={material.id}>
      <Td>{material.title}</Td>
      <Td>{material.qty}</Td>
      <Td></Td>
    </Tr>
  ))}
</Tbody>

可选:后续分页适配

如果之后后端需要支持分页,需协调后端修改返回结构为{count: number; results: T[]},再恢复FetchResponse<T>的使用。

内容的提问来源于stack exchange,提问作者Justin Boucher

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:38:13