传递JSON作为道具-无法读取未定义的属性“名称”

时间:2019-04-01 09:39:20

标签: javascript json reactjs

我正在发送JSON请求,该请求返回JSON对象。我想将数据移交给组件函数以进行显示,但是这样做的时候,它给了我错误:

无法读取未定义的属性“名称”

我在下面进行了总结,并附带了包含该功能的完整代码。


JSON:

http://api.openweathermap.org/data/2...c3ca2d4736dcfe

我将以上所有内容存储在状态中,然后将其作为道具传递:

<WeatherCard data={this.state.weatherdata} />

然后我可以将道具记录在函数中,然后得到:

Code:
 {cod: "200", message: 0.0081, cnt: 5, list: Array(5), city: {…}}
  city: {id: 2643743, name: "London", coord: {…}, country: "GB", population: 1000000}
  cnt: 5
  cod: "200"
  list: (5) [{…}, {…}, {…}, {…}, {…}]
  message: 0.0081
  __proto__: Object

我也可以记录props.data.city:

Code:
  {id: 2643743, name: "London", coord: {…}, country: "GB", population: 1000000}
  coord: {lat: 51.5085, lon: -0.1258}
  country: "GB"
  id: 2643743
  name: "London"
  population: 1000000
  __proto__: Object

所以您认为我可以执行 props.data.city.name 来获取城市名称,但是没有。我收到无法读取未定义的属性“名称”。

完整代码:


import React, { Component } from 'react';
import './App.css';
import WeatherCard from './components/WeatherCard'

const config = {
  API: "http://api.openweathermap.org/data/2.5/forecast?q=London,uk&units=metric&cnt=5&APPID=",
  API_KEY: process.env.REACT_APP_OPEN_WEATHER_MAP_API_KEY
}

class App extends Component {

  constructor() {
    super()
    this.state = {
      error: null,
      weatherdata: "",
      isLoaded: false
    }
  }

  componentDidMount() {
    fetch(config.API + config.API_KEY)
      .then( result => result.json() )
      .then ( 
        (result) => {
          this.setState({ 
            weatherdata: result,
            isLoaded: true
          })
      },
      (error) => {
        this.setState({
          isLoaded: false,
          error: error
        })
      }
    )
  }

  render() {
    return (
      <div className="App">
        <WeatherCard data={this.state.weatherdata} />
      </div>
    );
  }
}

export default App;


------

import React from 'react';

function WeatherCard(props) {
  console.log(props.data.city.name) <---- this fails
  return (
    <div>

    </div>
  )
}

export default WeatherCard

5 个答案:

答案 0 :(得分:0)

您对API的调用是异步的,并且您尝试在从API接收结果之前呈现WeatherCard组件。

仅当您有数据时,才使用isLoaded状态变量来呈现组件。

render() {
  return (
    <div className="App">
      {this.state.isLoaded && (<WeatherCard data={this.state.weatherdata} />)}
    </div>
  );
}

答案 1 :(得分:0)

在获取之前您的组件渲染给出了结果,所以就这样。  设置为初始状态

weatherdata: {}, 
  • 对于您的情况,天气数据应该是对象。

然后,在获取响应中,不设置整个响应,而是仅设置所需的数据

 this.setState({ 
            weatherdata: result.city,
            isLoaded: true
          })

答案 2 :(得分:0)

在尝试访问该API之前,该API可能未返回结果。尝试使用console.log(props);,您会发现props第一次是空的。

仅当WeatherCard设置为isLoaded时,才应渲染true组件。

类似的东西:

    {this.state.isLoaded && (<WeatherCard data={this.state.weatherdata} />)}

答案 3 :(得分:0)

尝试将props设置为componentWillMount ans中的状态,然后在组件内部使用

答案 4 :(得分:0)

您需要检查数据是否已加载..然后呈现无状态组件。

// Example stateless functional component
const SFC = props => (
  <div>{props.label}</div>
);

// Example class component
class Thingy extends React.Component {
  constructor() {
    super()
    this.state = {
      error: null,
      weatherdata: "",
      isLoaded: true
    }
  }

  componentDidMount() {
    fetch('https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22')
      .then( result => result.json() )
      .then ( 
        (result) => {
          this.setState({ 
            weatherdata: result,
            isLoaded: false
          })
      },
      (error) => {
        this.setState({
          isLoaded: false,
          error: error
        })
      }
    )
  }

  render() {
    return (
      <div className="App">
       {this.state.isLoaded? <h1>Loading...</h1> :  <WeatherCard data={this.state.weatherdata} />}
        </div>
    );
  }
}


function WeatherCard(props) {
  console.log(props)
  return (
    <div>
    This is weather Data
    </div>
  )
}

// Render it
ReactDOM.render(
  <Thingy title="I'm the thingy" />,
  document.body
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>