ComponentDidMount()之后找不到状态属性

时间:2018-09-10 15:21:05

标签: reactjs

我想练习我的reactjs技能,所以我正在通过流行的openweathermap api的api调用进行一些练习

我正在componentDidMount()周期中进行api调用,该周期遵循文档here,是进行异步调用的更好位置

如果我在渲染中使用console.log(data),我首先会变得不确定,然后会得到所需的对象;但是,如果我尝试使用确实存在的{data.city.name}访问该对象,则会在第二次重新渲染时收到错误“ TypeError:无法读取未定义的属性'name'”(componentDidMount()强制进行第二次渲染)

我不知道自己缺少什么,我对生命周期没有经验,但这很简单,我不明白为什么会这样

有人可以启发我吗?谢谢。

import React from 'react';

class WeekForecast extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      data: {}
    };
  }

  componentDidMount() {
    fetch([url]) 
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            data: result
          });
        },
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      )
  }

  render() {        
    const { data } = this.state;   
    return(
      <div> 
        <p>This weeks forecast in {data.city.name}</p>
      </div>
    )
  }

}

export default WeekForecast;

2 个答案:

答案 0 :(得分:1)

希望以下代码段有所帮助。 几个问题。

  1. Promise手柄被滥用。
  2. 在fir渲染上处理数据(在操作之前进行数据验证)。

class WeekForecast extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      data: {}
    };
  }
  fetch = () => Promise.resolve({city:{name:"New York City"}})

  componentDidMount() {
    this.fetch()
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            data: result
          });
        },
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      )
  }

  render() {        
    const { data } = this.state;   
    return(
      <div> 
        <p>This weeks forecast in {data.city && data.city.name || 'No City'}</p>
      </div>
    )
  }

}

ReactDOM.render(<WeekForecast />, document.querySelector("#app"))
<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>
<div id='app'/>

答案 1 :(得分:1)

您看到此错误,因为您正试图从undefined对象获取属性。如果您当时尝试记录undefined的属性是没有问题的,但是如果尝试从此undefined对象获取属性,则会收到错误消息。

const  data = {};

console.log( "city is", data.city );
console.log( "city name is", data.city.name );

这是另一个例子。如果我们没有为data定义一个空对象怎么办?您是在自己的州定义一个,但是如果我们不定义该怎么办?

//const  data = {};

console.log( "city is", data.city );
console.log( "city name is", data.city.name );

由于未定义data,因此无法将city作为undefined

在您的情况下,data在您的状态中定义为空对象。因此,尝试记录city会返回undefined,但是尝试记录city.name会返回错误。

由于在第一个渲染后数据将降落在组件中,因此应使用条件渲染检查数据是否存在。当您处理来自遥远地方的数据时,将一直使用它。有很多方法可以进行条件渲染。这是其中之一:

renderHelper() {
  const { data } = this.state;
  if ( !data.city ) { return <p>Loading data...</p>}
  return <p>This weeks forecast in {data.city.name}</p>
}

render() {
  return (
    <div>
      { this.renderHelper() }
    </div>
  )
}