Search code examples
javascriptgoogle-cloud-firestorereact-hookstailwind-cssresponsive-images

Why array is empty on render but if code is changed its fills


So I am fetching the urls from a firestore database and then using those urls for the img tags.

However, the issue I am facing is that when the page loads the array is empty but if I make a change to the code ( any change at all even an empty space ) the array will then populate as the useeffect triggers again.. I would like for it to get the data on the first fetch.

First line of the console log is when the page loads, then the second line is when I added a random space to a div

enter image description here

import React, { useEffect, useState } from "react"
import { proFirestore } from "../firebase/config"
import { collection, onSnapshot, query } from "firebase/firestore"

const Photos = () => {
  const [imgs, setImgs] = useState([])

  const fetchAllImgs = async () => {
    try {
      const collectionRef = collection(proFirestore, "images")
      const qry = query(collectionRef)

      await onSnapshot(qry, (querySnapshot) => {
        setImgs(
          querySnapshot.docs.map((doc) => ({
            id: doc.id,
            data: doc.data(),
          }))
        )
      })
    } catch (error) {}
  }

  useEffect(() => {
    fetchAllImgs()
    console.log(imgs)
  }, [])

  return (
    <div className="absolute mt-[5%] flex w-full items-center justify-center">
      <div className="">
        <div>
          <button className="h-20 w-20   rounded bg-black text-white"></button>
        </div>
        <div>
          <img className="h-full w-full cursor-pointer" src={imgs[0]}></img>
        </div>
      </div>
    </div>
  )
}
export default Photos

I have tried many things such as .map() which works, but I want to only render a single item from the array based on its index..

Any help would be great?


Solution

  • When loading the page, its best to use a ? to check the array before populating the div with the data, this works perfectly

    {imgs[1]?.data.imageUrl}