React中TypeError: data.map非函数但数据为数组的问题排查
解决React中TypeError: data.map is not a function(shadcn-ui Table渲染接口数据场景)
核心原因分析
你遇到的错误本质是尝试对非数组类型的值调用map方法,虽然控制台显示接口返回了长度为6的firmServices数组,但你实际传给Table组件的可能不是这个数组,而是其他类型(比如axios响应对象、包含数组的外层对象)。
具体解决方法
1. 确认正确提取接口返回的数组
axios的响应结构是包裹在res.data中的,你的接口返回数据应该类似这种结构:
{ "firmServices": [ { "id": 1, "name": "服务1" }, // ... 其他5条数据 ] }
如果直接把res.data赋值给状态,你拿到的是包含firmServices的对象,不是数组,自然无法调用map。
修正代码:
import { useState, useEffect } from 'react'; import axios from 'axios'; import { Table, TableBody, TableRow, TableCell } from '@/components/ui/table'; const ServicesList = () => { // 初始状态设为空数组,避免渲染时类型错误 const [services, setServices] = useState([]); useEffect(() => { axios.get('/your-api-endpoint') .then(response => { // 精准提取firmServices数组 setServices(response.data.firmServices); }) .catch(error => { console.error('获取服务数据失败:', error); }); }, []); return ( <Table> <TableBody> {/* 遍历正确的数组 */} {services.map(service => ( <TableRow key={service.id}> <TableCell>{service.name}</TableCell> {/* 根据你的数据结构渲染其他列 */} <TableCell>{service.description}</TableCell> </TableRow> ))} </TableBody> </Table> ); }; export default ServicesList;
2. 增加类型校验,避免渲染时的类型错误
即使正确提取了数组,也可能存在异步加载时初始状态或异常情况导致的类型问题,建议在渲染前做数组校验:
优化渲染逻辑:
<TableBody> {/* 先判断是否为数组,再执行map */} {Array.isArray(services) ? ( services.map(service => ( <TableRow key={service.id}> <TableCell>{service.name}</TableCell> </TableRow> )) ) : ( <TableRow> <TableCell colSpan={2}>数据加载中...</TableCell> </TableRow> )} </TableBody>
3. 排查异步请求的竞态问题(可选)
如果组件可能在请求完成前卸载,会导致状态更新错误,可使用AbortController终止请求:
useEffect(() => { const controller = new AbortController(); axios.get('/your-api-endpoint', { signal: controller.signal }) .then(response => setServices(response.data.firmServices)) .catch(error => { // 忽略请求被终止的错误 if (error.name !== 'CanceledError') { console.error('获取服务数据失败:', error); } }); // 组件卸载时终止请求 return () => controller.abort(); }, []);
快速排查步骤
- 在
setServices之前console.log(response.data),确认接口返回的结构是否符合预期 - 在渲染前
console.log(services),确认它是数组类型 - 检查初始状态是否为
[],而不是null或{}
内容的提问来源于stack exchange,提问作者Jbud
相关产品推荐
相关产品推荐

