1

我正在使用SpaceXAPI 来构建个人项目。我正在使用 React Router 动态加载组件,而不是刷新整个网站。

这是我LaunchDetails试图输出一些数据的组件:

import React, { Component } from 'react'

class LaunchDetail extends Component {
  state = {
    launch: []
  }

  async componentDidMount () {
    try {
      const res = await fetch(`https://api.spacexdata.com/v3/launches/${this.props.match.params.flight_number}`)
      const data = await res.json()
      this.setState({
        launch: data,
        rocket: data.rocket
      })
    } catch (e) {
      console.log(e)
    }
  }

  render () {
    const { launch, rocket } = this.state

    console.log(rocket)

    return (
      <div>
        <div>
          <h1>{launch.mission_name}</h1>
          <p>SpaceX Flight Number: {launch.flight_number}</p>
          <p>Launched: {launch.launch_year}</p>
          <p>Rocket: {rocket.rocket_name}, {rocket.rocket_type}</p>
        </div>
      </div>
    )
  }
}

export default LaunchDetail

深一层的数据launch.mission_name显示正确......但是,当我尝试下一层时,例如rocket.rocket_name (eg: launch.rocket.rocket_name),它会引发上述错误。

奇怪的是,这在另一个组件中有效,但它使用了不同的端点(所有数据),我正在通过它进行映射。不确定我在这个组件中调用数据的方式是否应该归咎于......

有谁知道为什么会发生这种情况?

编辑:收到一些评论后,我更新了代码以使其更简单,错误仍然存​​在:

import React, { Component } from 'react'

class LaunchDetail extends Component {
  state = {
    launch: []
  }

  async componentDidMount () {
    try {
      const res = await fetch(`https://api.spacexdata.com/v3/launches/${this.props.match.params.flight_number}`)
      const data = await res.json()
      this.setState({
        launch: data
      })
    } catch (e) {
      console.log(e)
    }
  }

  render () {
    const { launch } = this.state

    return (
      <div>
        <div>
          <h1>{launch.mission_name}</h1>
          <p>SpaceX Flight Number: {launch.flight_number}</p>
          <p>Launched: {launch.launch_year}</p>
          <p>Rocket: {launch.rocket.rocket_name}, {launch.rocket_type}</p>
        </div>
      </div>
    )
  }
}

export default LaunchDetail
4

1 回答 1

0

这里您可以发现反应生命周期方法按以下顺序排列。

componentWillMount -->渲染--> componentDidMount

你已经初始化了状态

state = {
  launch: []
}

所以在第一次渲染时,state.rocket将是未定义的。

要解决此问题,请初始化 state.rocket 或更改componentDidMountcomponentWillMount 首选前者。

注意componentWillMount在版本 17 中已弃用。


在OP的编辑之后。您仍在将启动初始化为 []

在第一次渲染launch.rocket时将是未定义的。因此launch.rocket.rocket_name会抛出错误。

要么初始化launch有一个rocket字段。或者做类似的事情

(launch.rocket || {}).rocket_namerocket,或在访问之前定义的其他要检查的内容rocket_name

于 2020-02-16T09:26:04.083 回答