3

I have a list of URLs to images. Each of these images sometimes load and sometimes 404 (meaning that an image that loaded at some point may disappear later).

let images = ['http://example.com/img1.jpg', ...];

Is there a way to request these images, to save them in memory if the request is successful, and to display those saved images in React?

componentDidMount() {
  this.setState({ savedImages: images.map(saveImage)} );
}

render() {
  return (
    <div><image src={this.state.savedImages[0]}/></div>
  );
}
raphaelrk
  • 757
  • 10
  • 17
  • 1
    You could use service worker to store images in cache. – dfsq Apr 25 '18 at 07:48
  • 1
    The question is not React-specific, I think. Once image is requested and loaded, it is saved in browser cache. The technique of preloading image with JS you can find there https://stackoverflow.com/questions/33894508/preload-image-with-javascript-and-css – Limbo Apr 25 '18 at 07:59
  • @LevitatorImbalance is there a way to tell if the image was successfully loaded? – raphaelrk Apr 25 '18 at 08:16
  • Yes see [here](https://stackoverflow.com/questions/7442821/javascript-jquery-event-listener-on-image-load-for-all-browsers?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa). But why wouldn't an image succesfully load? :D – DarkBee Apr 25 '18 at 08:20
  • @raphaelrk Yep :) https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/Attribute/image.onload – Limbo Apr 25 '18 at 08:50
  • @raphaelrk in your case: ```var img = new Image(); img.onload = yourAwesomeOnLoadHandler``` – Limbo Apr 25 '18 at 08:50
  • @DarkBee "why wouldn't an image successfully load" Facebook's rate limits on user profile pictures have been unpredictable as of late. A more real solution we'll add soon is saving the pictures server side but needed a quick client side solution first – raphaelrk Apr 25 '18 at 09:40
  • Don't u like need permissions to serve/store content from Facebook anyhow? – DarkBee Apr 25 '18 at 10:45
  • We have permissions, they [updated their policies](https://developers.facebook.com/blog/post/2018/04/19/facebook-login-changes-address-abuse/) recently -- even a logged in user looking at their own profile picture can get rate limited. – raphaelrk Apr 25 '18 at 12:09

1 Answers1

6

Okay, let me represent the whole information from comments as a complete answer.

Remark: The question is actually not React-specific, but vanilla JS.


The idea is to dynamically create the Image instance:

/* Somewhere inside the React class, I think */

preloadImages = () => {
    let links = ["link1", "link2", "link3"]

    /* the one react-specific thing is this.setState */
    this.setState({ images: links.map((link, i) => {
        // create an Image instance
        var img = new Image()
        // setting handler for load complete
        img.onload = () => this.handleImageLoad(i)
        // set the src attribute for it. After this line image loading will start
        img.src = link
        // return object with indicate of image loading statement
        return {
            url: link,
            loaded: false
        }
    }) })
}

// nuff said, I suppose, this function is clear :)
handleImageLoad = index => {
    var { images } = this.state
    images[index].loaded = true
    this.setState({ images })
}

Obviously, now you can use this.state.images in render and render only images that are already loaded :)

Shandy Sulen
  • 301
  • 2
  • 17
Limbo
  • 2,123
  • 21
  • 41