#react-native #react-native-android #react-native-image
#react-native #react-native-android #react-native-image
Вопрос:
У меня есть приложение, которое отображает несколько изображений, которые я загружаю из API. Теперь проблема в том, что срок действия некоторых изображений истек, что вызывает проблему на Android, в Android экран начинает отставать, как только на экране загружается изображение с истекшим сроком действия.
Я попытался заменить источник изображения onError={() => this.imgRefs[img_unique_id].setNativeProps({src: [{uri: this.state.workingUri}]})}
этим методом, но он не работает. Я не могу использовать локальное состояние, поскольку оно не сохраняет выходные данные в локальном состоянии.
Я попробовал следующий код
<Image
source={image.url}
progressiveRenderingEnabled={true}
ref={item.id}
onError={(e) => this.refs[item.id].setNativeProps({source: [{uri: "working image URL"}]})}
resizeMethod={"scale"}>
</Image>
Приведенный выше код выдает мне неопределенную ошибку setNativeProps, и если я не использую onError на Android, это показывает мне ошибку утечки памяти.
Комментарии:
1. Почему вы не можете использовать локальное состояние в этом случае?
2.просто используйте
native-base
вместо необработанных конструкций react-native,native-base
Image
поддерживает неудачные изображения, предоставляя вам поддержкуfallbackSource
или дажеfallbackComponent
Ответ №1:
Вот полный пример этого. Чтобы иметь собственное состояние для каждого FlatList
элемента, я создал класс.
import React, { Component, PureComponent } from 'react';
import { FlatList, Text, View, Image } from 'react-native';
class ItemClass extends PureComponent {
state = {
isImageExit: null
}
componentWillMount = () => {
const { task } = this.props;
Image.getSize(task.url, (width, height) => {
if(width>0){
this.setState({ isImageExit: true });
}
else{
this.setState({ isImageExit: false });
}
}, () => {
this.setState({ isImageExit: false });
});
}
render() {
const { isImageExit } = this.state;
const { task } = this.props;
const url = isImageExit ? task.url : 'https://dummyimage.com/600x400/000/fff';
if (isImageExit === null) {
return null;
}
return (
<Image
style={{ height: 200, width: 200 }}
source={{ uri: url }}
/>
);
}
}
export default class App extends Component {
render() {
const data = [
{ url: 'url' },
{ url:'https://cdn.pixabay.com/photo/2017/08/05/18/53/mountain-2585069_1280.jpg' },
];
return (
<View style={{alignItems: 'center', top: 50}}>
<FlatList
data={data}
renderItem={({ item }) => <ItemClass task={item} />}
/>
</View>
);
}
}
Комментарии:
1. ваш код работал отлично, но проблема остается той же, как только изображение ошибки появляется в представлении, приложение становится медленным.
2. Вместо того, чтобы ждать, пока изображение перейдет в состояние ошибки, как я могу использовать getSize для предварительной загрузки изображения?
3. Обновлено, может быть, так лучше? Сначала image.getSize попытается загрузить и получить размер изображения. Пока это работает, ничего не отображается, или вы можете отобразить загрузочный компонент или то, что хотите. Когда getSize будет завершен, изображение тоже будет отображаться.
4. Я внедрил изменение, оно все еще медленное, и я думаю, что изображения замедляют работу FlatList после дополнительной загрузки. Я пробовал без изображений, все работает нормально.
Ответ №2:
Я думаю, вам следует использовать данные, полученные из Api, и соответствующим образом установить состояние внутри componentWillReceiveProps
, потому что я думаю, что настройка состояния — лучший способ достичь этого результата. .
this.setState = { image: { uri: 'image_uri_from_api' } }
Внутри <Image>
добавить —
<Image style={ your_custom_style }
source={ this.state.image }
onError={ this.onError.bind(this) }
/>
Внутри onError
добавьте это —
onError(error){
this.setState({ image: require('your_local_image.path')})
}
Надеюсь, теперь это работает!
Комментарии:
1. Это react native, а не react web
2. спасибо, что дали мне знать. Я соответствующим образом обновил ответ.
3. Динамически загружается несколько изображений, как мне справиться с этой ситуацией?
4. да, я использую flatlist. На iOS это обрабатывается на стороне ОС, на Android это создает утечку памяти.
5. Есть ли способ, которым я могу передать функцию в исходном коде, которая сначала извлекает изображение, и в зависимости от размера я могу вернуть изображение или your_local_image ?.