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

React.js/Axios请求数据后调用map报错map is not a function

问题根因

map is not a function 报错的核心原因是你调用map的目标不是数组类型。
你初始化text状态时给的是空数组,但接口请求成功后赋值传错了值:从控制台打印的响应结构可以看到,response.data.data.proposals才是真正的提案列表数组,你现在直接执行setText(response.data),存进状态的是外层普通对象{data: {proposals: []}},普通对象本身没有map方法,渲染时调用自然触发报错。

修复方案
  • 修正状态赋值的取值路径,拿到真正的数组再存入状态,同时加空值兜底避免接口异常时的报错:
    把原来.then回调里的逻辑替换为以下代码即可
.then(function (response) {
  console.log(JSON.stringify(response.data));
  // 注意取值层级:axios返回的response.data是GraphQL接口的整体响应,内部data下的proposals才是列表数组
  const proposalList = response.data?.data?.proposals || [];
  setText(proposalList);
})
  • 把map逻辑加回渲染部分时,增加一层数组类型校验,覆盖请求未完成、接口返回异常的边界场景:
return (
  <Container component="main" maxWidth="xs">
    <Button
      fullWidth
      variant="contained"
      sx={{ mt: 3, mb: 2 }}
      onClick={() => CreateProposal()}
    >
      Create
    </Button>
    {/* 列表渲染区域 */}
    {Array.isArray(text) && text.map(item => (
      <div key={item.id}>
        <h3>{item.title}</h3>
        <p>作者:{item.author}</p>
        <p>状态:{item.state}</p>
        <p>{item.body}</p>
      </div>
    ))}
  </Container>
);
  • 你之前注释掉的字段转换逻辑也写错了取值目标,不能直接对response.data调用map,要拿到proposals数组之后再做字段映射。
可选优化项
  • 不要在useEffect内部用require('axios'),把axios的导入语句放到文件顶部即可,避免每次effect执行都重复加载依赖。
  • 你当前的请求逻辑混用了async/await和.then链式调用,选一种写法统一即可,比如全用async/await可读性更高:
useEffect(() =>{
  async function fetchData() {
    try {
      const reqData = JSON.stringify({
        query: `query Proposals {
          proposals (
            skip: 0,
            where: {
              space_in: ["zischan.eth"],
            },
            orderBy: "created",
            orderDirection: desc
          ) {
            id
            title
            body
            choices
            start
            end
            snapshot
            state
            author
            space {
              id
              name
            }
          }
        }`,
        variables: {}
      });

      const response = await axios.post('https://testnet.snapshot.org/graphql', reqData, {
        headers: headers
      })
      const proposalList = response.data?.data?.proposals || [];
      // 在这里统一做字段格式转换
      const formattedList = proposalList.map(d => ({
        id: d.id,
        author: d.author,
        title: d.title,
        state: d.state,
        body: d.body,
        end: d.end,
        start: d.start,
      }))
      setText(formattedList);
    } catch (error) {
      console.log(error);
    }
  }
  fetchData()
}, []);

注意:渲染列表时给每个项加key属性,优先用接口返回的唯一标识(比如这里每个提案的id字段),不要用数组下标当key,避免列表动态更新时出现渲染错位的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:51:20