Search code examples
iosreactjsreact-nativeimagereact-native-fast-image

How to reload image url one more time if url shows error in loading


I am trying to load images from URL on flatlist using Image Component. In this component there is a property (onError?: () => void ) this property is called on an image fetching error. When I run my app in low network some images failed to load, so what code should I write in (onError?: () => void ) so that the URL that failed to load images should load one more time in low network.

I am creating this App in React Native for iOS

I have done this :

App.js

import React, { useState } from 'react';
import Product from './product';
import {
  FlatList,
  SafeAreaView
} from 'react-native';

const products = [
  {productImage: "https://media.istockphoto.com/photos/poverty-concept-used-red-shoes-for-children-in-a-thrift-shop-between-picture-id1303292803?s=612x612"},
  {productImage: 'https://media.istockphoto.com/photos/poverty-concept-used-red-shoes-for-children-in-a-thrift-shop-between-picture-id1303292803?s=612x612'},
  {productImage: "https://media.istockphoto.com/photos/poverty-concept-used-red-shoes-for-children-in-a-thrift-shop-between-picture-id1303292803?s=612x612"},
  {productImage: 'https://media.istockphoto.com/photos/poverty-concept-used-red-shoes-for-children-in-a-thrift-shop-between-picture-id1303292803?s=612x612'},
]

const App = () => {
  return (
    <SafeAreaView>
      <FlatList 
      numColumns={2}
      data={products}
      keyExtractor={(item, index) => index.toString()}
      renderItem={({ item }) => (<Product product={item} />)}>
</FlatList>
    </SafeAreaView>
  );
};

export default App;

product.js

import React from 'react';
import { View, Image } from 'react-native';

class Product extends React.Component {

    constructor(props){
     super(props);
     this.state = {
       uri : this.props.product.productImage,
       errorCount : 0
     }
    }

    passInError(e) {
      const { productImage } = this.props.product
          if (this.state.errorCount < 3) {
            this.setState({uri: productImage, errorCount: ++this.state.errorCount})
            console.log(" Corrupt Image URL : " + productImage )
            console.log(" Corrupt Image Error Reason : ", JSON.stringify(e) )
            console.log (" Corrupt Image Reload Count : ", this.state.errorCount)
          }
        }

    render() {
        return (
            <View>
              <Image
                 style={{ width: 200, height: 200, borderWidth: 2, }}
                 source={{ uri:this.state.uri }}
                 onError = {e => this.passInError(e.nativeEvent) }
                 key = {this.state.errorCount}
              />
            </View>
        )
    }
}

export default Product;

What code should I write in (onError?: () => void ) function to reload failed images URL ?


Solution

  • Try setting image url in state and update when error on loading image.

    product.js

    import React from 'react';
    import { View } from 'react-native';
    import FastImage from 'react-native-fast-image';
    
    class Product extends React.Component {
        constructor(props){
         super(props);
         this.state = {
           uri : this.props.product.productImage,
           errorCount : 0
         }
        }
    
        render() {
            const { productImage } = this.props.product
            return (
                <View>
                  <FastImage
                     style={{ width: 200, height: 200, borderWidth: 2, }}
                     source={{ uri:this.state.uri }}
                     resizeMode={FastImage.resizeMode.contain}
                     onError={e =>
                       this.state.errorCount < 3 &&
                       this.setState(
                         {uri: '', errorCount: ++this.state.errorCount},
                           () => this.setState({uri: productImage}),
                       )
                     }
                  />
                </View>
            )
        }
    }
    
    export default Product;