开发者问题收集

React - 从 Mongo 渲染数据时未定义的属性

2020-05-11
268

好的,今天的战斗结束了。请帮忙。尝试编写我的第一个应用程序。我决定使用 MERN 堆栈,但在连接前端和后端时遇到了问题。 后端工作正常,我在 Postman 中收到数据。 代码和说明如下,请记住,这是我用来检查问题解决方案的游乐场代码。最高级别的 KISS 可提取一个问题。 开始吧,反应代码:

import React from 'react';


class App extends React.Component {
  constructor(props){
    super(props)

    this.state = {
      arr:[] 
    }
  }
    componentDidMount() {
      fetch('http://localhost:4001/animals')
        .then(response => response.json())
        .then(data => {
          var outputArr = Object.keys(data).map(key => {return data[key]})
          return outputArr
        })
        .then(data => {
          console.log('seting state: ')
          console.log(data)// first object is 'success' boolean, second is array of documents from mongo
          this.setState({ arr:data[1] })
        });     
    }

  render(){
    console.log('array in this.state: ')
    console.log(this.state.arr)
    //console.log(this.state.arr[1].name) - this is crashing code - TypeError

    return (
      <div className="App">
        <p>rendering App</p>
        <hr></hr>  
        <p>{/*this.state.arr[1].name*/}</p>
      </div>
    ); 
  }
}

export default App;

在控制台中,我看到数据正常:

array in this.state:
[
  {
    "_id": "5eb6d1097726ef7946027fd6",
    "name": "Matylda",
    "type": "kot",
    "birth_date": "01.01.2010",
    "foto_path": "",
    "status": "active"
  },
  {
    "_id": "5eb6d1097726ef7946027fd7",
    "name": "Fuks",
    "type": "kot",
    "birth_date": "01.01.2008",
    "foto_path": "",
    "status": "active"
  }
//and so on...

]

但是当我尝试访问特定数据(例如,注释部分中的名称)时,我收到“TypeError:无法读取未定义的属性‘name’”。 尝试了许多不同的方法。如果我将对象的测试数组添加为变量,则一切都正常。我感觉这和来自 api 的对象中的键有关,但我不知道哪里出了问题以及如何让它工作。

3个回答

要理解您的问题,您需要对 React 生命周期钩子 有所了解。

您正在 componentDidMount 钩子中获取数据,该钩子在 render 之后运行,此时组件已经安装到 DOM。

因此,当您的组件第一次安装时, this.state.arr 仍然只是一个空数组,您尚未设置从状态中获取的数据。

如果您将状态对象初始化为:

this.state = {
  arr: null
}

...然后在您的 render 中执行任何其他操作之前,请设置如下条件:

render(){
  if (!this.state.arr) return <h1>Fetching Data...</h1>
  // The rest of your render here...
}

这应该可以防止您的应用在数据获取之前第一次尝试渲染组件时不会崩溃。同时提供一条有用的消息,表明组件仍在等待来自 API 的数据(您可以将 h1 替换为微调器组件或其他加载状态组件)。

希望这有帮助!!

DexDeLeon
2020-05-12

由于 this.state.arr 是一个对象,您应该能够使用 this.state.arr.name 而不是 this.state.arr[1].name 来访问名称字段。

seas and mountains
2020-05-11

尝试 this.state.arr['0'].name... 数据可能是一个对象,您可以通过属性名称以字符串形式获取它们,即使它们看起来像数字。

如果有帮助请告诉我

Oswald Rijo
2020-05-11