Img 标签无法访问 src 的对象

Img tag can't access an object for the src

在这个 React 组件中,我试图将一个对象设置为 URL 用于 Imgsrc。但是,我不断收到错误消息: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 useStateuseEffect 而不是 componentDidMount()

您收到此错误,因为初始状态为 loading: false

在您第一次渲染时(在您为 API 调用设置 loading: true 之前)它会尝试渲染。

因此let frontSprite = this.state.loading ? "Loading..." : this.state.character.sprites.front_default将失败,因为this.state.character的初始值是{}并且{}.sprites给出未定义导致错误。

要解决此问题,您可以在 character: {} 时尽早 return。

解决方案是创建一个名为 front_default 的新状态,它将存储 this.state.character.sprites.front_default 的 url。获取数据后,front_default 等于 URL 的值。

import React, {Component} from "react"
class App extends Component {
    constructor() {
        super()
        this.state = {
            loading: false,
            character: {},
            front_default: "",
        }
    }
    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,
                    front_default: data.sprites.front_default
                })
            console.log(this.state.character.name)
            })      
    }

    render() {
        const text = this.state.loading ? "loading..." : this.state.character.name
        let frontSprite = this.state.loading ? "Loading..." : this.state.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