反应-未处理的拒绝(TypeError):无法读取未定义的属性“ city”

时间:2020-07-11 04:07:30

标签: javascript reactjs

我目前正在开发一个网站,可在此处检索团队信息:

export default class TeamInfo extends React.Component{
    
    constructor(props) {
        super(props);
     
        this.state = {
          isShow: true,
          team: []
        };
        this.getTeam();
      }    

    getTeam(){
        const axios = require("axios");
        const team_id = this.props.id;
        axios.get(API+'/team/'+ team_id).then(res => {
            this.setState({team : res.data})
            console.log('inside teaminfo... ' + this.state.team.location.city);
        })
    }
 render() {
        return(
         <div><h1>{this.state.team.location.city}</h1></div>
)}
}

这是团队JSON答案的结构:

{
    "name": "Barcelona",
    "shield": "shield.png",
    "location": {
        "city": "Barcelona",
        "country": "SPAIN"
    },
    "score": 74626,
}

我尝试以this.state.team.location.city 的身份访问团队位置,当我在控制台中登录时可以正确显示,但网站上显示Unhandled Rejection (TypeError): Cannot read property 'city' of undefined

任何提示或帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

鉴于组件代码,您的state.team是一个数组,因此您需要使用数组索引对其进行访问。

this.state.team[0].location.city

OFC,这是假定已填充数组,因此请先使用防护检查以确保第一个元素存在。

this.state.team[0] && this.state.team[0].location.city

您也可以有条件地渲染它

export default class TeamInfo extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      isShow: true,
      team: []
    };
    this.getTeam();
  }

  getTeam() {
    const axios = require("axios");
    const team_id = this.props.id;
    axios.get(API + "/team/" + team_id).then(res => {
      this.setState({ team: res.data });
    });
  }
  render() {
    return this.state.team[0] ? (
      <div>
        <h1>{this.state.team[0].location.city}</h1>
      </div>
    ) : null;
  }
}

而且由于它是一个数组,所以映射结果也是一种常见的模式

export default class TeamInfo extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      isShow: true,
      team: []
    };
    this.getTeam();
  }

  getTeam() {
    const axios = require("axios");
    const team_id = this.props.id;
    axios.get(API + "/team/" + team_id).then(res => {
      this.setState({ team: res.data });
    });
  }
  render() {
    return (
      {this.state.team.map(team => (
        <div>
          <h1>{team.location.city}</h1>
        </div>
      ))}
    );
  }
}

注意:

this.setState({team : res.data})
console.log('inside teaminfo... ' + this.state.team.location.city);

状态更新是“异步的”,更新发生在渲染周期之间,因此控制台日志将 记录 this中的当前状态 渲染周期。将更新后的状态记录在生命周期函数中,例如componentDidUpdate

答案 1 :(得分:1)

您的团队数据在您的构造函数中初始化如下

this.state = {
  isShow: true,
  team: []
};

由于未定义.team.location.city,因此在第一次渲染期间导致了错误。在第二个渲染上,将setState设置为新值后很好。

要解决此问题,您需要检查该值是否未定义或在构造函数中为location.city设置初始值。

render() {
        return(
         <div><h1>{typeof this.state.team.location !== "undefined"  && typeof this.state.team.location.city !== "undefined" && this.state.team.location.city}</h1></div>
)}

答案 2 :(得分:0)

您还可以使用新的ES2020链运算符来检查对象内部是否存在这样的属性:

  render() {
    return (
  {this.state.team.map(team => (
    {team?.location ?<div><h1>{team.location.city}</h1></div>: null}
  ))}
  );        
  }

链运算符?。如果在团队内部未找到undefined,将返回location,否则返回对象。