1

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}/>
  
   }):""}
  • "_I want images to show up at the same time._" do you mean you have several times the code you show, with separate loading? Would be great sharing a [mcve]. – ghybs Dec 14 '22 at 13:08
  • I mean, when I open the page and react starts the fetching process, images are appearing almost one by one. But I want them to appear all at once. – Fuad Rustamzade Dec 14 '22 at 13:13
  • 1
    It is still difficult to understand your situation, since there is no information abour your several images. Is data for all images in the single fetched data? Or do you have 1 `useEffect` like this per image? – ghybs Dec 14 '22 at 15:16
  • I changed the code a little. Could you look at it, please? – Fuad Rustamzade Dec 15 '22 at 07:50
  • You can use [React Query](https://tanstack.com/query/v4) if it's a big project. It comes with what you want and lot of other good features. – Amanshu Kataria Dec 16 '22 at 05:48

1 Answers1

1

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.

ghybs
  • 47,565
  • 6
  • 74
  • 99