解析 JSON 个对象数组并在 ReactJS 中显示它

Parsing JSON objects array and displaying it in ReactJS

最近我的 React 应用程序遇到了一个奇怪的问题。我正在尝试解析包含数据数组的 JSON 对象。数据是这样的:

{"Place":"San Francisco","Country":"USA","Author":{"Name":"xyz","Title":"View from the stars"}, "Year":"2018", "Places":[{"Price":"Free", "Address":"sfo"},{"Price":"$10","Address":"museum"}] }

数据包含多个数组,就像我刚刚展示的 Author 示例一样。我有一个从 URL 中获取此数据的函数。我在 componentDidMount 中调用该函数。该函数获取数据,即 responseJson,然后将其存储在我使用 setState 设置的名为 result 的空数组中。在我的状态下,我得到的结果是:[]。我的代码看起来像这样:

this.setState({result:responseJson})

现在,当我尝试从结果中访问作者姓名时,出现错误。所以像这样:

{this.state.result.Author.Name}

我在一个用于显示内容的函数中执行此操作。我在渲染函数的 return 中调用此函数。我收到一条错误消息:

TypeError: 无法读取未定义的 属性 'Name'。如果我尝试任何低于内部水平的东西,我会得到同样的错误。如果我显示 {this.state.result.Place} 或 {this.state.result.Country} 一切都很好。但如果我尝试,说 {this.state.result.Author.Title} 或 {this.state.result.Places[0].Price} 它会给我同样的错误。 令人惊讶的是,我已经在我的不同组件中解析了同一个对象,并且没有出现任何错误。谁能解释一下为什么会这样?

如果我在 fetch 调用函数中设置状态时存储单个元素,我可以显示它。例如:

{result:responseJson,
 AuthorName:responseJson.Author.Name
 }

然后我可以继续将其用作 {this.state.AuthorName}。

请帮我找到解决这个问题的方法。提前致谢!

可能是您的状态对象在第一次呈现时为空,并且仅在请求完成后(即第一次呈现后)使用 API 中的数据更新。 Name 和 Place 属性不会引发错误,因为它们可能解析为未定义。

尝试在您的渲染方法中放置一个 if 块来检查结果是否已加载,如果没有则显示加载指示器。

我猜你的初始状态是这样的:

{ results: {} }

不看更多代码很难说。

[编辑]:从聊天中添加注释

数据在第一次呈现时不可用。呈现此组件的事件序列如下所示:

  1. 实例化组件,初始状态设为{ results: [] }
  2. 组件已安装,API 调用已触发(注意,这是异步的,并且 return 数据还没有)
  3. 第一次调用渲染方法。这发生在数据从 API 请求 return 编辑之前,因此状态对象仍然是 {results: [] }。此时任何获取作者的尝试都会引发错误,因为 results.Authorsundefined
  4. API请求returns数据,setState调用更新状态为{ results: { name: 'test', author: [...] } }。这将触发组件
  5. 的re-render
  6. 第二次调用渲染方法。只有此时,状态对象中才有数据。

如果这个状态发生变化,意味着它在 componentDidMount 时发生了变化,或者在获取之后或其他任何情况下发生了变化,很可能你的状态首先是空的,然后它填充了你的数据。

所以你得到这个错误的原因很简单,反应试图在 this.state.result.Author 甚至存在之前得到 this.state.result.Author.Name。

要得到它,先测试this.state.result.Author,如果确实有东西,然后像这样得到Author.Name。

render(){
    return(
        <div>
            {this.state.result.Author ? this.state.result.Author.Name : 'not ready yet'}
        </div>
    );

}

[编辑] 我会在这里回答评论: 只是因为他们在对象中处于更高的层次。

this.state.result 将始终 return 某些东西,如果您的状态中没有 result 键(例如,当组件安装时构造函数中没有结果键),即使是 false 也是如此。

this.state.result.Country 如果 result 不是构造函数中状态的键,将显示相同的错误。但是,如果在你的构造函数中定义了result,那么它一开始就是假的,然后在新状态填充时成为数据。

this.state.result.Author.Name 又更深一层...

因此,为了避免它,您必须在构造函数中定义整个 "schema"(在我看来, 不好的做法)。如果我没记错的话,下面的代码在获取 this.state.result.Author.Name 时不会抛出任何错误。它首先 return false,然后是可用的值。

constructor(props){
super(props);
    this.state={
        result: {
            Author: {}
        }
    }
}