从状态中反应多次获取
React Multiple Fetch from state
所以我尝试使用 homeworld id 获取我的 SWAPI json-server 两次以获取 homeworld 名称,但我只得到 "TypeError: Cannot read property 'name' of undefined"。我对 React 还很陌生,所以如果它看起来很乱,我很抱歉!提前致谢!
import React, { Component } from 'react';
import './Card.css';
const person = personID =>
`http://localhost:3008/people/${personID}`
const picture = pictureID =>
`http://localhost:3008/${pictureID}`
// const planet = planetID =>
// `http://localhost:3008/planets/${planetID}`
class Card extends Component {
constructor(props){
super(props);
this.state ={
requestFailed: false,
person: 1,
planet: 4
}
}
componentDidMount(){
fetch(person(this.state.person))
.then(response => {
if(!response.ok) {
throw Error("Network Request Failed");
}
return response
})
.then(d => d.json())
.then(d => {
this.setState({
cardData: d
})
}, () => {
this.setState({
requestFailed: true
})
})
fetch(`http://localhost:3008/planets/${this.state.cardData.homeworld}`)
.then(data => data.json())
.then(data => {
this.setState({
homeData: data
})
})
}
render() {
if(this.state.requestFailed === true) return <p>Error please try
again!</p>
if(!this.state.cardData) return <p>Loading ...</p>
return (
<div className='card'>
<div className='card-content'>
<div className='card-name'>{this.state.cardData.name}</div>
<img src={picture(this.state.cardData.image)}
alt='profile'/>
<p>
<span>Birthday:</span>
<span>{this.state.cardData.birth_year}</span>
</p>
<p>
{/* Note that in order to get the homeworld's name, you have to get the planet name from a different endpoint than the people */}
<span>Homeworld:</span>
<span>{this.state.homeData.name}</span>
</p>
</div>
</div>
);
}
}
export default Card;
第一个问题似乎是您试图在 homeData.name
加载之前进行渲染。您可能应该进行类似于 cardData
加载检查的加载检查。或者您可以在加载之前不渲染任何内容:
{this.state.homeData ?
<span>{this.state.homeData.name}</span> :
<span>Loading...</span>
}
第二个问题是您在第一个 fetch
的同时进行 homeData
的第二个 fetch
。所以这一行:
fetch(`http://localhost:3008/planets/${this.state.cardData.homeworld}`)
总是会失败,因为 cardData
在运行时还没有加载到状态。
你应该做的是将它移到第一个请求的响应部分:
fetch(person(this.state.person))
.then(response => {
if(!response.ok) {
throw Error("Network Request Failed");
}
return response
})
.then(d => d.json())
.then(d => {
this.setState({
cardData: d
})
fetch(`http://localhost:3008/planets/${d.homeworld}`)
.then(data => data.json())
.then(data => {
this.setState({
homeData: data
})
})
}, () => {
this.setState({
requestFailed: true
})
})
将它们提取到单独的函数中以稍微清理一下会有所帮助。
所以我尝试使用 homeworld id 获取我的 SWAPI json-server 两次以获取 homeworld 名称,但我只得到 "TypeError: Cannot read property 'name' of undefined"。我对 React 还很陌生,所以如果它看起来很乱,我很抱歉!提前致谢!
import React, { Component } from 'react';
import './Card.css';
const person = personID =>
`http://localhost:3008/people/${personID}`
const picture = pictureID =>
`http://localhost:3008/${pictureID}`
// const planet = planetID =>
// `http://localhost:3008/planets/${planetID}`
class Card extends Component {
constructor(props){
super(props);
this.state ={
requestFailed: false,
person: 1,
planet: 4
}
}
componentDidMount(){
fetch(person(this.state.person))
.then(response => {
if(!response.ok) {
throw Error("Network Request Failed");
}
return response
})
.then(d => d.json())
.then(d => {
this.setState({
cardData: d
})
}, () => {
this.setState({
requestFailed: true
})
})
fetch(`http://localhost:3008/planets/${this.state.cardData.homeworld}`)
.then(data => data.json())
.then(data => {
this.setState({
homeData: data
})
})
}
render() {
if(this.state.requestFailed === true) return <p>Error please try
again!</p>
if(!this.state.cardData) return <p>Loading ...</p>
return (
<div className='card'>
<div className='card-content'>
<div className='card-name'>{this.state.cardData.name}</div>
<img src={picture(this.state.cardData.image)}
alt='profile'/>
<p>
<span>Birthday:</span>
<span>{this.state.cardData.birth_year}</span>
</p>
<p>
{/* Note that in order to get the homeworld's name, you have to get the planet name from a different endpoint than the people */}
<span>Homeworld:</span>
<span>{this.state.homeData.name}</span>
</p>
</div>
</div>
);
}
}
export default Card;
第一个问题似乎是您试图在 homeData.name
加载之前进行渲染。您可能应该进行类似于 cardData
加载检查的加载检查。或者您可以在加载之前不渲染任何内容:
{this.state.homeData ?
<span>{this.state.homeData.name}</span> :
<span>Loading...</span>
}
第二个问题是您在第一个 fetch
的同时进行 homeData
的第二个 fetch
。所以这一行:
fetch(`http://localhost:3008/planets/${this.state.cardData.homeworld}`)
总是会失败,因为 cardData
在运行时还没有加载到状态。
你应该做的是将它移到第一个请求的响应部分:
fetch(person(this.state.person))
.then(response => {
if(!response.ok) {
throw Error("Network Request Failed");
}
return response
})
.then(d => d.json())
.then(d => {
this.setState({
cardData: d
})
fetch(`http://localhost:3008/planets/${d.homeworld}`)
.then(data => data.json())
.then(data => {
this.setState({
homeData: data
})
})
}, () => {
this.setState({
requestFailed: true
})
})
将它们提取到单独的函数中以稍微清理一下会有所帮助。