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; }
相关数据说明
- React Query DevTools响应结果:返回的是纯物料数组,而非
{count: number; results: T[]}结构 data控制台日志:输出为包含多个物料对象的数组,每个对象包含id、title、slug、qty属性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
相关产品推荐
相关产品推荐

