Search code examples
javascriptreactjsfirebasererender

React re-render does not work. img src does not load


the code below is supposed to download 5 urls from firebase and when it is already downloaded, it passes 1 url to "currentUrl" state. after that url should be passed to <img url.../> below and img should load. the problem is, img does not load... . and I am 100% sure that "currentUrl" actually contains proper url afer a few milliseconds.

custom useFirestore hook uses useEffect in order to fetch the 5 urls.

SLIDER.JS

import "./Slider.css"
import {useEffect, useState} from "react";
import {useFirestore} from "../../../hooks/useFirestore";
 
 
const Slider = () => {
 
    const [currentUrl, setCurrentUrl] = useState("")
 
 
//////in useFirestore hook, use effect downloads 5 urls from firebase and pass them to 
/////// photoUrls state
 
      const {sliderUrls:photoUrls} = useFirestore()
 
    useEffect(()=>{
        if (photoUrls){
            setCurrentUrl(photoUrls[0])
 
    },[photoUrls, currentUrl])
 
    return (
        <div className="slider">
            <img className="slider-img" src={currentUrl} alt="photo"/>
        </div>
    );
 
};
 
export default Slider;

USEFIRESTORE.JS

import {useEffect, useState} from "react";
import {storage} from "../firebase/config"
import {ref, getDownloadURL} from "firebase/storage";


export const useFirestore = () => {
    const [sliderUrls, setSliderUrls]  = useState(null)


useEffect(()=>{

    const results = [];
    for (let i = 1; i < 6; i++) {
        getDownloadURL(ref(storage, `slider/slider-${i}.png`)).then((url)=>{
            results.push(url)
        })
    }
    setSliderUrls(results)
},[])




    return {sliderUrls};
}

Solution

  • if you have 100% of the time an image i think you are lucky. For me just looking at the code your result is always empty.

    import {useEffect, useState} from "react";
    import {storage} from "../firebase/config"
    import {ref, getDownloadURL} from "firebase/storage";
    
    
    export const useFirestore = () => {
        const [sliderUrls, setSliderUrls]  = useState(null)
    
      const fetchFirestoreImages = useCallback(async () => {
          const promises = [];
          for (let i = 1; i < 6; i++) {
              const urlPromise = getDownloadURL(ref(storage, `slider/slider-${i}.png`));
              promises.push(urlPromise);
           }
           return Promise.all(promises)
      }, [])
    
    
    useEffect(()=>{
    
        fetchFirestoreImages().then(urls => {
          setSliderUrls(urls)
        })
        
    },[fetchFirestoreImages])
    
        return {sliderUrls};
    }