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

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();
}, []);

快速排查步骤

  1. 在setServices之前console.log(response.data),确认接口返回的结构是否符合预期
  2. 在渲染前console.log(services),确认它是数组类型
  3. 检查初始状态是否为[],而不是null或{}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 22:41:04