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

React状态中无法访问API返回的recipes数组元素问题求助

为什么React组件中能访问API返回的count却无法访问recipes数组的publisher字段?

问题描述

我正在从外部API获取美食食谱数据,返回的JSON格式如下:

{ "count": 30, "recipes": [ { "publisher": "BBC Food", "f2f_url": "http://food2fork.com/view/8c0314", "title": "Chicken and cashew nut stir-fry", "source_url": "http://www.bbc.co.uk/food/recipes/chickenandcashewnuts_89299", "recipe_id": "8c0314", "image_url": "http://static.food2fork.com/chickenandcashewnuts_89299_16x9986b.jpg", "social_rank": 95.91061636245128, "publisher_url": "http://www.bbc.co.uk/food" }, { "publisher": "Jamie Oliver", "f2f_url": "http://food2fork.com/view/0beb06", "title": "Roasted chicken breast with pancetta, leeks & thyme", "source_url": "http://www.jamieoliver.com/recipes/chicken-recipes/roasted-chicken-breast-with-pancetta-leeks-and-thyme", "recipe_id": "0beb06", "image_url": "http://static.food2fork.com/466_1_1349094314_lrg2129.jpg", "social_rank": 94.88568903341375, "publisher_url": "http://www.jamieoliver.com" }, { ... 更多食谱 ... } ] }

我尝试在React组件中测试展示count值以及数组中第一个食谱的publisher字段,我的React代码如下:

import React from 'react';
import './App.css';
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { data: {} };
  }
  componentDidMount() {
    fetch('https://www.food2fork.com/api/search?key=MY_KEY&q=chicken%20breast&page=2')
      .then(response => {
        return response.json();
      })
      .then(jsonData => {
        this.setState({ data: jsonData }, function() {
          console.log(jsonData);
        });
      });
  }
  render() {
    return (
      <div className="App">
        <h1>{this.state.data.count}</h1>
        <p>{this.state.data.recipes[0].publisher}</p> // 为何这行无法正常工作?
      </div>
    );
  }
};

当移除render函数中的<p>标签时,页面能正常加载并在获取数据后显示count值30;但保留该标签时会报错。我已排查两小时仍未找到原因,为何能访问count却无法访问数组内的publisher字段?该如何正确访问recipes数组中的元素?

解决方案

问题根源

问题出在组件初始渲染时的数据状态:

  • 你初始化state.data为一个空对象{},此时this.state.data.count的值是undefined,React在渲染时会直接忽略undefined,不会抛出错误。
  • 但this.state.data.recipes同样是undefined,你尝试访问undefined[0]就会触发Cannot read properties of undefined (reading '0')的错误,这就是页面报错的原因。
  • 直到componentDidMount中的请求完成并更新state后,data才会包含recipes数组,但初始渲染时这个数组还不存在。

几种修复方法

1. 使用可选链操作符(推荐,ES2020+支持)

可选链操作符?.会在访问的属性/值为undefined或null时直接返回undefined,避免报错:

<p>{this.state.data.recipes?.[0]?.publisher}</p>

2. 条件渲染

通过判断recipes是否存在且有元素,再进行渲染:

{this.state.data.recipes && this.state.data.recipes.length > 0 && (
  <p>{this.state.data.recipes[0].publisher}</p>
)}

3. 初始化state时预设空数组

在构造函数中把data.recipes初始化为空数组,这样初始渲染时recipes[0]是undefined,访问publisher会返回undefined,不会报错:

constructor(props) {
  super(props);
  this.state = { data: { recipes: [] } };
}

4. 添加加载状态

如果想在数据加载完成前显示加载提示,可以添加一个loading状态:

constructor(props) {
  super(props);
  this.state = { data: {}, loading: true };
}

componentDidMount() {
  fetch('https://www.food2fork.com/api/search?key=MY_KEY&q=chicken%20breast&page=2')
    .then(response => response.json())
    .then(jsonData => {
      this.setState({ data: jsonData, loading: false });
    });
}

render() {
  if (this.state.loading) {
    return <div className="App">加载中...</div>;
  }
  
  return (
    <div className="App">
      <h1>{this.state.data.count}</h1>
      <p>{this.state.data.recipes[0].publisher}</p>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:02:47