javascriptreactjsamazon-web-servicesamazon-s3

Add image files into react state using 'useState'


import React, { useState } from "react";

export default function App() {
  const [photo, setPhoto] = useState([]);
  const pictures = listObjects();  // getting image flies from AWS.S3, and they are array of objects, and the key "Key" contains image files like "dog.gif"
  const getAllPictures = (pics) => {
    pics.then((data) => {
      return data.forEach((picture) => {
        // console.log(picture.Key); I've got a stirng img file
        setPhoto((photo) => [...photo, picture.Key]);
      });
    });
  };
  getAllPictures(pictures);

Hi. I'm trying to put a list of image files, like "dog.gif", into react state using hooks, and I used a wrapper function. Now I don't see any error on my local server, but after a couple of seconds later, my laptop fan spins and never stops until I close the browser, also occasionally I can see the spinning beach ball on my laptop. I'm guessing I'm either doing wrong to put the list into the state, or I'm getting too much data from AWS.S3. Can anyone point me out what am I doing wrong here, please?


Solution

  • You may want to set the state once, otherwise it will run into an infinite re-render loop.
    You could initialize some data on component mount with useEffect hook.

    Here is an example using useEffect:

    import React, { useState, useEffect } from "react";
    
    export default function App() {
      const [photo, setPhoto] = useState([]);
    
      const getAllPictures = (pics) => {
        pics.then((data) => {
          return data.forEach((picture) => {
            // console.log(picture.Key); I've got a stirng img file
            setPhoto((photo) => [...photo, picture.Key]);
          });
        });
      };
    
      useEffect(() => {
        const pictures = listObjects();
        getAllPictures(pictures);
      }, [])
    
    

    What is wrong with the current implementation:

    export default function App() {
      // photo has an initial value
      const [photo, setPhoto] = useState([]);
      const pictures = listObjects();
    
    
      const getAllPictures = (pics) => {
        pics.then((data) => {
          return data.forEach((picture) => {
            // The setState will trigger a re-render
            setPhoto((photo) => [...photo, picture.Key]);
          });
        });
      };
    
      // On each setState (re-render) this function will be executed
      getAllPictures(pictures);