проверить, существует ли изображение с fetch (функция не возвращает ответ) - PullRequest
0 голосов
/ 20 февраля 2020

У меня есть следующая функция, чтобы проверить, существует ли изображение (аватар) на сервере. Если это так, аватар отображается. Если нет, отображается аватар по умолчанию.

export const Avatar = props => {

    const userId = props.userId

    const size = props.size ? props.size : 25

    fetch(URL.Avatar + '/' + userId + '_avatar.jpg').then(res => {
        if (res.status === 404) {
            return (
                <Image source={{uri: URL.Avatar + '/default.jpg' }} style={{
                    width: size,
                    height: size,
                    borderRadius: size / 2
                }} />                
            )
        } else {
            return (
                <Image source={{uri: URL.Avatar + '/' + userId + '_avatar.jpg' }} style={{
                    width: size,
                    height: size,
                    borderRadius: size / 2
                }} />                
            )
        }
    }).catch(err => {
        return (
            <Image source={{uri: URL.Avatar + '/default.jpg' }} style={{
                width: size,
                height: size,
                borderRadius: size / 2
            }} />                
        )
    })

}

Однако эта функция не работает. Я получаю ошибку «ничего не было возвращено из рендера», потому что функция считает, что оператор возврата (в конце) отсутствует. Однако, когда я добавляю в него несколько console.logs, сама загрузка работает. URL-адреса правильные, потому что, когда я помещаю возврат в конце с компонентом Image, он работает.

Кто-нибудь знает, в чем может быть проблема? Это как-то связано с asyn c?

Ответы [ 3 ]

2 голосов
/ 20 февраля 2020

Fetch asyn c и вернется позже, чем вы ожидаете, потому что код продолжит выполняться, пока fetch ожидает ответа.

Вы можете решить эту проблему с помощью awaiting извлечения и создания функции async

export const Avatar = async props => {

    const userId = props.userId

    const size = props.size ? props.size : 25

    return await fetch(URL.Avatar + '/' + userId + '_avatar.jpg').then(res => {
        if (res.status === 404) {
            return (
                <Image source={{uri: URL.Avatar + '/default.jpg' }} style={{
                    width: size,
                    height: size,
                    borderRadius: size / 2
                }} />                
            )
        } else {
            return (
                <Image source={{uri: URL.Avatar + '/' + userId + '_avatar.jpg' }} style={{
                    width: size,
                    height: size,
                    borderRadius: size / 2
                }} />                
            )
        }
    }).catch(err => {
        return (
            <Image source={{uri: URL.Avatar + '/default.jpg' }} style={{
                width: size,
                height: size,
                borderRadius: size / 2
            }} />                
        )
    })

}
1 голос
/ 20 февраля 2020

Нет необходимости самостоятельно извлекать изображение перед его использованием, оно избыточно. Вместо этого вы можете использовать функцию onError компонента Image, чтобы определить, что изображение не удалось загрузить. Вы можете сохранить URL-адрес в состоянии компонента и изменить его в соответствии с состоянием успеха / сбоя (см. Функцию onLoad, чтобы определить, что изображение было успешно загружено).

В качестве альтернативы, Вы можете установить изображение по умолчанию, которое будет отображаться во время загрузки через опору defaultSource в качестве заполнителя.

1 голос
/ 20 февраля 2020

Похоже, у вас нет действительного оператора return для этой функции. Я не уверен, как выглядит ваш ответ на запрос, если изображение не существует, но что произойдет, если вы установите значение по умолчанию за пределами fetch?

Примерно так:

export const Avatar = props => {

    const userId = props.userId

    const size = props.size ? props.size : 25

    fetch(URL.Avatar + '/' + userId + '_avatar.jpg').then(res => {
        if (res.status === 404) {
            return (
                <Image source={{uri: URL.Avatar + '/default.jpg' }} style={{
                    width: size,
                    height: size,
                    borderRadius: size / 2
                }} />                
            )
        } else {
            return (
                <Image source={{uri: URL.Avatar + '/' + userId + '_avatar.jpg' }} style={{
                    width: size,
                    height: size,
                    borderRadius: size / 2
                }} />                
            )
        }
    }).catch(err => {
        // Handle actual errors here
    })

    return (
        <Image source={{uri: URL.Avatar + '/default.jpg' }} style={{
            width: size,
            height: size,
            borderRadius: size / 2
        }} />                
    )
}
...