Reactjs TypeError:无法读取属性';火箭名称';未定义的,即使已定义
我正在使用Reactjs TypeError:无法读取属性';火箭名称';未定义的,即使已定义,reactjs,api,react-router,Reactjs,Api,React Router,我正在使用SpaceXAPI构建一个个人项目。我使用React路由器动态加载组件,而不是刷新整个网站 这是我的LaunchDetails组件,我试图在其中输出一些数据: import React, { Component } from 'react' class LaunchDetail extends Component { state = { launch: [] } async componentDidMount () { try { const
SpaceX
API构建一个个人项目。我使用React路由器动态加载组件,而不是刷新整个网站
这是我的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
从中可以发现,react生命周期方法的顺序如下
componentWillMount-->渲染-->componentDidMount
您已使用初始化状态
状态={
发布:[]
}
因此,在第一次渲染时,state.rocket
将是未定义的
要解决此问题,请初始化state.rocket或将componentDidMount
更改为componentWillMount
前者更受欢迎
注意componentWillMount
在版本17中不推荐使用
在OP的编辑之后。您仍在将启动初始化为[] 在第一次渲染时,
launch.rocket
将被取消定义。因此,launch.rocket.rocket\u name
将抛出一个错误
初始化launch
以获得rocket
字段。或者做类似的事情
(launch.rocket | |{}).rocket_name
,或者在访问rocket_name
之前检查rocket
是否已定义的其他方法,您可以发现react生命周期方法的顺序如下
componentWillMount-->渲染-->componentDidMount
您已使用初始化状态
状态={
发布:[]
}
因此,在第一次渲染时,state.rocket
将是未定义的
要解决此问题,请初始化state.rocket或将componentDidMount
更改为componentWillMount
前者更受欢迎
注意componentWillMount
在版本17中不推荐使用
在OP的编辑之后。您仍在将启动初始化为[] 在第一次渲染时,
launch.rocket
将被取消定义。因此,launch.rocket.rocket\u name
将抛出一个错误
初始化launch
以获得rocket
字段。或者做类似的事情
(launch.rocket | |{}).rocket_name
,或者其他一些东西,在访问rocket_name
之前检查rocket
是否定义了rocket_name我很确定这不是由“3层深”属性引起的,但在渲染中更是如此:rocket.rocket_name
。火箭最初不是在状态中定义的,因此this.state.rocket
将是未定义的,它的access子属性将给出您正在获取的错误。您可以在componentDidMount
中获取数据,但在第一次渲染后会调用该生命周期方法。因此,如果您应该有一个用于呈现的加载状态(用于获取数据时),并且最好是状态的默认值,请尝试在初始状态中初始化rocket
={launch:[]}
确定,因此我将rocket
添加到状态,仍然是相同的错误。我现在已经删除了它,因此它现在引用了launch.rocket.rocket\u name
,但错误仍然存在……我很确定这不是由“3级深度”属性引起的,但在渲染中更是如此:rocket.rocket\u name
。火箭最初不是在状态中定义的,因此this.state.rocket
将是未定义的,它的access子属性将给出您正在获取的错误。您可以在componentDidMount
中获取数据,但在第一次渲染后会调用该生命周期方法。因此,如果您应该有一个用于呈现的加载状态(用于获取数据时),并且最好是状态的默认值,请尝试在初始状态中初始化rocket
={launch:[]}
确定,因此我将rocket
添加到状态,仍然是相同的错误。我现在删除了它,因此它现在引用了launch.rocket.rocket\u name
,但错误仍然存在……谢谢,这是我的代码:launch:{rocket:[]}
希望您能看到这个,为什么我需要初始化rocket
和该组件中的任何其他数据的状态,而不是调用所有数据的其他组件中的状态?我希望这是有意义的…您需要在该组件中初始化火箭状态的唯一原因是第一次渲染。正如你所假设的,总是会有一个launch
对象,它有一个rocket
道具,这个道具有rocket\u name
字段。我个人不希望在这个组件中初始化rocket,而是在渲染中使用类似(launch.rocket | |{})。rocket\u name
。这样,如果rocket
未定义,访问rocket\u name
不会抛出错误,只会不渲染任何内容。在rocket
通过componentDidMount
初始化后,它将呈现新的rocket\u名称
谢谢,这是我的代码:launch:{rocket:[]}
希望您能看到,为什么我需要初始化rocket
和该组件中的任何其他数据的状态,而不是调用所有数据的其他组件中的状态?我希望这是有意义的…您需要在该组件中初始化火箭状态的唯一原因是第一次渲染。正如你所假设的,总是会有一个launch
对象,它有一个rocket
道具,这个道具有rocket\u name
字段。我个人不希望在这个组件中初始化rocket,而是在渲染中使用类似(launch.rocket | |{})。rocket\u name
。这样,如果rocket
未定义,访问rocket\u name
不会抛出错误,只会不渲染任何内容。通过componentDidMount
初始化rocket
后,它将呈现新的rocket\u名称
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