开发者问题收集

“TypeError:无法读取未定义的属性‘name’”错误

2018-12-16
2672

代码给了我这个“TypeError:无法读取未定义的属性‘name’”错误,尽管当我使用 console.log 时它给了我对象

import React from "react";

class Random extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      breweries: []
    };
  }

  componentDidMount() {
    fetch("https://api.openbrewerydb.org/breweries")
      .then(response => response.json())
      .then((data) => {
        this.setState({
          breweries: data,
        })
      })
  }

  render() {
    const brewery = this.state.breweries[Math.floor(Math.random()*this.state.breweries.length)];
    return(
      <div>{brewery.name}</div>
    )
  }
}

export default Random;
3个回答

直到异步请求完成,

this.state.breweries[Math.floor(Math.random()*this.state.breweries.length)] 

实际上将返回 undefined ,因为

Math.floor(Math.random()*this.state.breweries.length)

将返回 0 ,并且由于 this.state.breweries 是一个空数组,它将返回 undefined

( [][0] -> undefined )。


您必须确保 brewery 尚未定义的可能性,例如:

<div>{brewery && brewery.name}</div>
kind user
2018-12-16

有两种方法可以解决此问题。

方法 1: UNSAFE_componentWillMount()

您可以使用 UNSAFE_componentWillMount() 代替 componentDidMount()UNSAFE_componentWillMount() 在组件呈现之前执行,因此您将在内容呈现之前获得处于状态的数据。这应该可以消除错误。

方法 2:验证状态是否为 !Empty

在您的 render 方法中,您可以添加一个 if 语句,表示如果状态中没有数据,则 breweriesnull ,否则 breweries 等于 this.state.breweries[Math.floor(Math.random()*this.state.breweries.length)]

类似这样:

render() {
    const { breweries } = this.state;
    let brewery; 
    if (breweries.length === 0){
       brewery = null;
    } else {
      brewery= 
   this.state.breweries[Math.floor(Math.random()*this.state.breweries.length)];
    }
    return(
      <div>{brewery.name}</div>
    )
  }

为了更加保险,您可以将这两种方法结合起来。如果您这样做,您的组件将如下所示:

import React from "react";

class Random extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      breweries: []
    };
  }

  componentWillMount() {
    fetch("https://api.openbrewerydb.org/breweries")
      .then(response =>{ return response.json() })
      .then((data) => {
        this.setState({
          breweries: data,
        })
      })
  }

  render() {
    const { breweries } = this.state;
        let brewery; 
        if (breweries.length === 0){
           brewery = null;
        } else {
          brewery= 
       this.state.breweries[Math.floor(Math.random()*this.state.breweries.length)];
        }
    return(
      <div>{brewery.name}</div>
    )
  }
}

export default Random;

应该可以。希望这能有所帮助。

编辑:警告

我写了 willMount(),但它应该是 UNSAFE_componentWillMount()。 componentWillMount() 在版本 17 之后将无法工作。 UNSAFE_componentWillMount() 在版本 17 之后将可以工作。很抱歉。我忘了写 unsafe。

Bens Steves
2018-12-16

在尝试访问数组的索引之前,您应该确保已获取数据。当数组为空时,您的随机数学运算将计算为 0 ,从而导致 undefined

import React from "react";

class Random extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      breweries: null
    };
  }

  componentDidMount() {
    fetch("https://api.openbrewerydb.org/breweries")
      .then(response => response.json())
      .then((data) => {
        this.setState({
          breweries: data,
        })
      })
  }

  render() {
    if (this.state.breweries) {
      const brewery = this.state.breweries[Math.floor(Math.random()*this.state.breweries.length)];
      return(
        <div>{brewery.name}</div>
      )
    }

    return null
  }
}

export default Random;
Sam Denty
2018-12-16