Тег img не может получить доступ к объекту для src - PullRequest
0 голосов
/ 25 апреля 2020

В этом компоненте React я пытаюсь установить объект в качестве URL для Img s src. Однако я продолжал получать ошибку: 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

Ответы [ 3 ]

0 голосов
/ 25 апреля 2020

Вы получаете эту ошибку, потому что начальное состояние loading: false.

При вашем первом рендеринге (до того, как вы установите loading: true для вызова API) он попытается рендериться.

Таким образом let frontSprite = this.state.loading ? "Loading..." : this.state.character.sprites.front_default потерпит неудачу, поскольку начальное значение this.state.character равно {}, а {}.sprites дает неопределенное значение, приводящее к ошибке.

Чтобы решить эту проблему, вы можете сделать ранний возврат, когда character: {}.

0 голосов
/ 27 апреля 2020

Решением было создание нового состояния с именем front_default, в котором будет храниться URL-адрес this.state.character.sprites.front_default. После того, как данные извлечены, 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
0 голосов
/ 25 апреля 2020

Ошибка из-за того, что ссылка на объект не определена. Это может быть связано с функцией жизненного цикла 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'];
}

Найти прикрепленный снимок результата. Снимок выполнения кода

Предложение:

Вы можете использовать React Hooks useState и useEffect вместо componentDidMount()

...