[在此React组件中,我试图将一个对象设置为Img
的src
的URL。但是,我不断收到错误:TypeError: Cannot read property 'front_default' of undefined (/App.js:33)
。这是在Scrimba课程中
import React, {Component} from "react"
class App extends Component {
constructor() {
super()
this.state = {
loading: false,
character: {}
}
}
componentDidMount() {
this.setState({loading: true})
fetch("https://pokeapi.co/api/v2/pokemon-form/1")
.then(response => response.json())
.then(data => {
this.setState({
loading: false,
character: data
})
console.log(this.state.character.name)
console.log(this.state.character.sprites.front_default)
})
}
render() {
const text = this.state.loading ? "loading..." : this.state.character.name
let frontSprite = this.state.loading ? "Loading..." : this.state.character.sprites.front_default
// The url that the img should get: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/shiny/1.png"
return (
<div>
<img src={frontSprite}/>
<p>{text}</p>
<p>{frontSprite}</p>
</div>
)
}
}
export default App
错误是由于对象引用未定义。这可能是由于React 生命周期函数 componentDidMount在获取操作之后没有重新渲染。
我对代码进行了以下更改,效果很好。
let text = this.state.loading ? "loading..." : this.state.character.name;
let sprites = this.state.loading ? "loading...": this.state.character.sprites;
let front_default = "";
if(sprites && sprites !== "loadding..."){
front_default = sprites['front_default'];
}
查找结果的所附快照。 Code execution snapshot
建议:
您可以使用React Hooks useState
和useEffect
代替componentDidMount()
您收到此错误,因为初始状态为loading: false
。
在您的第一个渲染(在为API调用设置loading: true
之前,它将尝试渲染。
因此let frontSprite = this.state.loading ? "Loading..." : this.state.character.sprites.front_default
将失败,因为this.state.character
的初始值为{}
,并且{}.sprites
给出了未定义的错误。
为解决这个问题,您可以在character: {}
时提早归还。