Fuad Rustamzade
Fuad Rustamzade

Reputation: 31

How to implement isLoading logic in React right?

The fetching is not going smoothly. I want images to show up at the same time. Here is how I have done it:

const [isLoading, setIsLoading] = useState(false)

useEffect(()=>{
    setIsLoading(true)
    fetch(url).then(res=>res.json()).then(data=>{
      setPhoto(data)
      setIsLoading(false)
    })
  },[url])

And then, I check, if isLoading is true, then I return "Loading" text. Else, the code should return the images page:

return (
    <div className="App">
      <header>.....
 {isLoading?<p className={'text-5xl mt-11'}>Loading...</p>:<div className={'flex flex-wrap space-x-2 justify-around '}>
   {photos?photos.hits.map((photo, index)=>{
    return <img className={'m-5 h-80 rounded-2xl'} onClick={handleClickOnPicture} key={photo.webformatURL} src={photo.webformatURL}/>
  
   }):""}

Upvotes: 1

Views: 498

Answers (1)

ghybs
ghybs

Reputation: 53290

Your images loading actually happens in 2 steps:

  1. You fetch your image URL's (data stored in photo state), for which you properly handle isLoading state
  2. You display the <img> elements with src attribute populated with URL's from step 1; but this is only the point where the browser knows of these new media resources, and starts fetching their content: this explains why you see your images appearing 1 by 1; the <img> element is there, but its actual content is still being fetched

To force the browser fetching your images content before you display them, the classic solution is to create an Image (HTMLImageElement) and to populate their src attribute. The browser starts requesting their content even if these objects are not actually inserted into the DOM.

Then you need to know when these images have finished loading in the background. For that, we use the onload property on the <img>, which adds an event listener that is called when the content has been retrieved (and cached) by the browser.

Once all images have finished loading, we can insert them into the DOM (possibly through new <img> elements, provided that they re-use the same URL's), and the browser will use its cached data to display them "instantly".

See e.g. How to preload images in React.js? for how to implement step 2 in details with React.

Upvotes: 1

Related Questions