【问题标题】:Json API access error with ReactReact 的 Json API 访问错误
【发布时间】:2018-11-28 15:07:59
【问题描述】:

我正在尝试从 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返回的Json是这样的:

[
    {
        "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 的异步访问导致的吗?谁能帮我解决这个问题?

【问题讨论】:

    标签: javascript json reactjs async-await


    【解决方案1】:

    你的组件被渲染了两次:

    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>
            )
        }
    }
    

    通常的做法是在组件第一次渲染时渲染“正在加载...”消息或微调器,没有数据,如下所示:

    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>
        )
    }
    

    【讨论】:

    • 很高兴为您提供帮助 ?
    【解决方案2】:

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

    在你的渲染方法中试试这个,

    render() {
    
        if (!(this.state.page && this.state.page.length && this.state.page[0].infoBloco))
          return null;
    
        return (
          <div>
            Exemplo
          </div>
        )
    }
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        你在 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),
              }))
          }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-04-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-05-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多