TypeError: Невозможно прочитать свойство 'rocket_name' из undefined - даже если оно определено - PullRequest
1 голос
/ 16 февраля 2020

Я использую SpaceX API для создания личного проекта. Я использую 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, отображаются правильно ... Однако, когда я пытаюсь и go вниз на другой уровень, скажем, 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

1 Ответ

0 голосов
/ 16 февраля 2020

С здесь вы можете обнаружить, что методы жизненного цикла реакции go в следующем порядке.

componentWillMount -> render -> componentDidMount

Вы инициализировали состояние с

state = {
  launch: []
}

Таким образом, при первом рендеринге state.rocket будет неопределенным.

Кому исправьте это, либо инициализируйте state.rocket, либо измените componentDidMount на componentWillMount с предпочтительным первым.

Примечание componentWillMount устарело в версии 17.


После OP редактировать. Вы по-прежнему инициализируете запуск в []

. При первом рендере launch.rocket будет неопределенным. Поэтому launch.rocket.rocket_name выдаст ошибку.

Либо инициализируйте launch, чтобы иметь поле rocket. Или сделайте что-то вроде

(launch.rocket || {}).rocket_name, или что-то еще, чтобы проверить, что rocket определено перед доступом к rocket_name.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...