React的Json API访问错误

时间:2018-06-19 15:28:04

标签: javascript json reactjs async-await

我正在尝试通过API访问Json中的以下变量:

page[0].infoBloco[0].tabela[0].dados[0].fonte.nome

我遇到了错误:

TypeError: this.state.page[0] is undefined[Learn More] index.jsx:49

API返回的杰森是这样的:

[
    {
        "infoBloco": [
            {
                "tabela": [
                    {
                        "dados": [
                            {
                                "fonte": {
                                    "url": "http://www.google.com",
                                    "nome": "Site de buscas"
                                }
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "infoBloco": [
            {
                "tabela": [
                    {
                        "dados": [
                            {
                                "fonte": {
                                    "url": "http://www.yahoo.com",
                                    "nome": "Outro site de buscas"
                                }
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

React页面代码是这样的:

import React, { Component } from "react"

export default class extends Component {

  constructor(props) {
    super(props)
    this.state = { 
      page: [],
    }
  }

  componentDidMount() {
    this.getData()
  }

  getData = async () => {
    await fetch('http://localhost:3003/api')
      .then(resp => resp.json())
      .then(data => this.setState({ 
        ...this.state, 
        page: data,
      }))
  }

  render() {

    console.log(this.state.page[0].infoBloco[0].tabela[0].dados[0].fonte.nome)

    return (
      <div>
        Exemplo
      </div>
    )
  }
}

console.log(this.state.page)返回完整的json

console.log(this.state.page[0])返回第一个json对象

console.log(this.state.page[0].infoBloco)返回错误TypeError: this.state.page[0] is undefined[Learn More] index.jsx:49

我只能访问页面[0],当我尝试访问其他内部元素时,它返回相同的错误。可能是由于异步访问API导致此错误?谁能帮我解决这个问题?

4 个答案:

答案 0 :(得分:0)

您的组件呈现两次:

  1. 根据构造函数中的指定,使用state.page = []进行第一个渲染
  2. 安装后,将加载页面数据并更新状态(componentDidMount方法)
  3. 状态更新后,再次呈现组件 ,这次页面数据处于状态

您收到错误消息是因为第一次呈现组件时,还没有state.page[0],因为尚未加载数据。

您可以通过添加if语句来解决此问题,以修正代码:

import React, { Component } from "react"

export default class extends Component {

    constructor(props) {
        super(props)
        this.state = {
            page: [],
        }
    }

    componentDidMount() {
        this.getData()
    }

    getData = async () => {
        await fetch('http://localhost:3003/api')
            .then(resp => resp.json())
            .then(data => this.setState({
                ...this.state,
                page: data,
            }))
    }

    render() {

        if (this.state.page[0]) {
            console.log(this.state.page[0].infoBloco[0].tabela[0].dados[0].fonte.nome)
        }

        return (
            <div>
                Exemplo
            </div>
        )
    }
}

通常的做法是,在第一次渲染组件时,在没有数据的情况下渲染诸如“ loading…”消息或微调框之类的东西,如下所示:

render() {

    if (!this.state.page[0]) {
        return <div>Loading, please wait…</div>
    }

    return (
        <div>
            Exemplo: {this.state.page[0].infoBloco[0].tabela[0].dados[0].fonte.nome}
        </div>
    )
}

答案 1 :(得分:0)

在api响应之前调用渲染器进行条件访问,这会导致undefined错误

if(this.state.page[0])
console.log(this.state.page[0].infoBloco[0].tabela[0].dados[0].fonte.nome)

答案 2 :(得分:0)

这肯定是由于API调用的异步特性。在状态中更新API响应之前,您不应该渲染组件。

在您的渲染方法中尝试一下,

render() {

    if (!(this.state.page && this.state.page.length && this.state.page[0].infoBloco))
      return null;

    return (
      <div>
        Exemplo
      </div>
    )
}

答案 3 :(得分:-2)

您在react-native中使用try JSON.stringify

 getData = async () => {
    await fetch('http://localhost:3003/api')
      .then(resp => resp.json())
      .then(data => this.setState({ 
        ...this.state, 
        page: JSON.stringify(data),
      }))
  }