Home > Enterprise >  State not updating properly
State not updating properly

Time:07-27

I'm trying to get some images from my firebase storage like this:

const [images, setImages] = useState([]);

  useEffect(() => {
    function list() {
      const storage = getStorage();
      const imagesRef = ref(storage, "test/");

      listAll(imagesRef)
        .then((res) => {
          res.items.forEach((item) => {
            getDownloadURL(item).then((url) => setImages([...images, url]));
          });
        })
        .catch((error) => {
          console.error(error);
        });
    }
    list();
  }, []);

console.log(images);

As you can see I'm trying to get an array with all the images that are found in the storage.

The code seems to work, I'm not getting any errors but my state isn't updating properly. I'm expecting something like [imageUrl1, imageUrl2, ...] but the logs are showing only one image url at the time: Log screenshot

CodePudding user response:

...images will not work when looping like this. The last image will be the only one written to the state. Instead, get a list of all the images first, then call setImages(images).

Promise.all can come in handy for this.

Promise.all(res.items.map(item => getDownloadURL(item))).then(images => setImages(images))

CodePudding user response:

You have to first add all images in a temporary array and then use the state to store them in the array. The below example will help you understand better.

 export default function App() {
  const [nodes, setNodes] = useState([]); 
  let arr = [];
   const refresh = async () => {
     for (var i = 0; i < 5; i  ) {
       arr.push(Math.random());
     }
    setNodes(arr);
   };
  useEffect(() => {
    refresh();
  }, []);

  return (
    <div className="App">
      {nodes.map((v) => (
        <div>value: {v}</div>
      ))}
    </div>
  );
  }
  • Related