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

React嵌套JSON映射组件报错:render未返回内容问题排查

问题分析与修复方案

需求与报错

需要调用API获取嵌套JSON数据,展示每个series的名称和已拥有卡牌数(cards_owned),但代码运行时报错:

Error: SeriesData(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.

原始JSON结构

{"count": 1,"results": [{"legends_total": {"series": "Legends Total","stubs_needed": 346556,"total_cost": 1224043,"cards_owned": 282,"cards_required": 352,"collection_excluded": "Faces of the Franchise"},"cover_athletes": {"series": "Cover Athletes","stubs_needed": 0,"series_cost": 101798,"cards_owned": 12,"cards_required": 12},"second_half": {"series": "2nd Half","stubs_needed": 53257,"series_cost": 96962,"cards_owned": 11,"cards_required": 22}}]}

出错的原始代码

const BrettCollection = props => {
  const [brettDataIsLoading, setBrettDataIsLoading] = useState(false)
  const [inventoryBrettData, setInventoryBrettData] = useState([])

  const fetchData = useCallback(async () => {
    setBrettDataIsLoading(true)
    axios
      .get(
        `https://api.showzone.io/api/user-inventory/${props.currentUser?.uid}/legends-collection/`
      )
      .then(async getUserInventoryLegendData => {
        if (getUserInventoryLegendData.data) {
          setInventoryBrettData(getUserInventoryLegendData.data.results[0])
          setBrettDataIsLoading(false)
        } else {
          setBrettDataIsLoading(false)
        }
      })
      .catch(err => {
        setBrettDataIsLoading(false)
      })
  }, [props.currentUser?.uid])

  useEffect(fetchData, [fetchData])

  const SeriesData = () => {
    Object.keys(inventoryBrettData)?.map((series, data) => {
      return (
        <>
          <h1>Series: {data.series}</h1>
          <p>Cards Owned: {data.cards_owned}</p>
        </>
      )
    })
  }

  return (
    <>
      {!brettDataIsLoading ? (
        <Card mb={6}>
          <CardContent>
            <Typography variant="h4" gutterBottom>
              Brett Collection
            </Typography>
            <Grid container spacing={6}>
              <Grid item xs={12} md={6}>
                <SeriesData />
              </Grid>
            </Grid>
          </CardContent>
        </Card>
      ) : (
        <>
          <LoaderBaseballInline></LoaderBaseballInline>
        </>
      )}
    </>
  )
}

修复步骤与修正后代码

核心问题点

  1. SeriesData组件未返回渲染结果:组件内的map函数执行后没有被返回,导致组件无输出。
  2. map参数使用错误:Object.keys()返回的是对象键名数组,map的第一个参数是键名,第二个是索引,不是数据对象,需通过键名从inventoryBrettData中获取对应数据。
  3. 初始状态类型不匹配:inventoryBrettData初始值设为数组[],但API返回的是对象,应改为{}避免遍历异常。
  4. 缺少列表key属性:React列表渲染需给每个元素添加唯一key,消除控制台警告。

修正后完整代码

import React, { useState, useCallback, useEffect } from 'react';
import { Card, CardContent, Typography, Grid } from '@mui/material';
import axios from 'axios';
import LoaderBaseballInline from './LoaderBaseballInline'; // 假设组件路径正确

const BrettCollection = props => {
  const [brettDataIsLoading, setBrettDataIsLoading] = useState(false);
  // 初始值改为空对象,匹配API返回的数据类型
  const [inventoryBrettData, setInventoryBrettData] = useState({});

  const fetchData = useCallback(async () => {
    setBrettDataIsLoading(true);
    try {
      const getUserInventoryLegendData = await axios.get(
        `https://api.showzone.io/api/user-inventory/${props.currentUser?.uid}/legends-collection/`
      );
      if (getUserInventoryLegendData.data) {
        setInventoryBrettData(getUserInventoryLegendData.data.results[0]);
      }
    } catch (err) {
      console.error('获取数据失败:', err);
    } finally {
      setBrettDataIsLoading(false);
    }
  }, [props.currentUser?.uid]);

  useEffect(fetchData, [fetchData]);

  const SeriesData = () => {
    // 用Object.entries直接获取键值对,更直观;同时添加return返回渲染结果
    return Object.entries(inventoryBrettData).map(([key, data]) => (
      <div key={key}> {/* 添加唯一key */}
        <h1>Series: {data.series}</h1>
        <p>Cards Owned: {data.cards_owned}</p>
      </div>
    ));
  };

  return (
    <>
      {!brettDataIsLoading ? (
        <Card mb={6}>
          <CardContent>
            <Typography variant="h4" gutterBottom>
              Brett Collection
            </Typography>
            <Grid container spacing={6}>
              <Grid item xs={12} md={6}>
                <SeriesData />
              </Grid>
            </Grid>
          </CardContent>
        </Card>
      ) : (
        <LoaderBaseballInline />
      )}
    </>
  );
};

export default BrettCollection;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 15:36:08