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

React中如何在state存储复杂JSON对象并渲染对应UI内容

报错根因

组件首次渲染的时机早于接口请求返回时间,你初始state里的excelData是空对象,不存在data属性,直接对undefined调用.map()方法就会抛出类型错误。
你之前把excelData初始值改成数组、接口回调只存response.data.data能跑通列表,是因为数组本身自带map方法,首次渲染遍历空数组不会报错,但这种写法把excelData变成了纯数组结构,根本存不下接口返回的support、page等同级字段,没法满足多字段渲染的需求,不是正确方案。

正确实现步骤

1. 给state设置和接口结构匹配的初始值

按照接口返回的JSON结构定义初始state,把data初始为空数组、support初始为空对象,既保证首次渲染时调用map不报错,也能完整存储整个接口返回的复杂结构:

state = {
  excelData: {
    page: 0,
    per_page: 6,
    total: 0,
    total_pages: 0,
    data: [],
    support: {}
  },
  loading: false,
  error: null
}

2. 修正生命周期请求逻辑

注意setState是异步方法,你原来写在axios请求后面的console.log拿不到更新后的state值,需要打印的话要写到setState的回调里,另外补上请求异常捕获:

componentDidMount(){
  this.setState({ loading: true })
  axios.get('https://reqres.in/api/unknown')
    .then((response) => { 
      this.setState({
        excelData: response.data,
        loading: false
      })
      // 要打印更新后的值在这里写
      // console.log(this.state.excelData)
    })
    .catch(err => {
      this.setState({
        error: err.message,
        loading: false
      })
    })
}

3. 渲染时增加安全兜底,同时渲染多部分内容

渲染时建议通过可选链做兼容兜底,避免接口返回结构异常时页面崩溃,同时可以分别读取不同字段渲染对应UI:

render(){
  const { excelData, loading, error } = this.state

  if(loading) return <div>数据加载中...</div>
  if(error) return <div>加载失败:{error}</div>

  return (
    <div>
      {/* 渲染分页字段 */}
      <div className="page-info">
        <p>当前第{excelData.page}页,共{excelData.total_pages}页,总计{excelData.total}条数据</p>
      </div>

      {/* 渲染data数组列表 */}
      <ListGroup>
        {
          excelData.data?.map(item => (
            <ListGroupItem key={item.id}>
              <span style={{color: item.color}}>名称:{item.name}</span>
              <span style={{marginLeft: '16px'}}>发布年份:{item.year}</span>
              <span style={{marginLeft: '16px'}}>潘通色号:{item.pantone_value}</span>
            </ListGroupItem>
          ))
        }
      </ListGroup>

      {/* 渲染support对象内容 */}
      <div className="support-tip" style={{marginTop: '24px', padding: '12px', background: '#f5f5f5', borderRadius: '4px'}}>
        <p>{excelData.support?.text}</p>
      </div>
    </div>
  )
}
额外注意点
  • 你当前代码里导入了useState和useEffect但没有使用,这两个是函数组件专属的Hook,类组件场景下可以直接删除这两个导入,减少无用代码。
  • 类组件的setState会自动合并顶层state属性,更新excelData这类独立字段时,不需要手动展开旧的this.state,直接赋值新值即可。
  • 可选链操作符?.是ES2020标准语法,Create React App 3及以上版本默认支持。如果你的项目构建版本较老不支持该语法,可以换成(excelData.data || []).map()的写法做兜底,效果完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:48:36