我正在使用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
这样的较深数据正在正确显示...但是,当我尝试向下一层,如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
答案 0 :(得分:0)
在here中,您可以发现react生命周期方法按以下顺序进行。
componentWillMount -> 渲染-> 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
是否已定义。