Search code examples
reactjsstaterendering

React Component not reflecting props


I have a functional component that takes in an array as and the setState func for that array as props.

When the component mounts, it gets files and sets the state. The state is set successfully, I've seen it in dev tools.

When the component appears on my screen, in the DevTools I see the props are set too to what they're supposed to be, but the .map() in my JSX returns nothing even though the array has items.

Code:

ParentComponent:

const [postFiles, setPostFiles] = useState([]);

Child Component: (React Dropzone hook)

Props: post (has url to get images), postFiles, setPostFiles

    useEffect(() => {    
      if (post) {
        let oldImages = []  
        post.images.forEach((image) => {
          axios.get(image.image).then(res => {
            let blob = new Blob([res.data], {type:'image/png'});
            blob.lastModifiedDate = new Date();
            let file = new File([blob], getImageName(image.image), 
                                {type:'image/png'});
            file.preview = image.image;
            oldImages.push(file);    
          })
       })
       setFiles(oldImages);
      }
    }, [post])

And i have this const that's rendered in my JSX:

    const thumbs = files.map(file => (
      <div className="thumb" key={uuidv4()}>   
        <div className="thumb-inner">    
          <a onClick={() => removeFile(file)} className="remove-image">    
            <i className="fal fa-times-circle"></i>    
          </a>    
          <img src={file.preview} />
        </div>
      </div>
    ));

Even though the files state is successfully changed, it does not reflect in my component where I render {thumbs} until I click something else in the component


Solution

  • The following may work, you are trying to access oldImages before it's been set since axios.get is asynchronous:

    Promise.all(
      post.images.map((image) =>
        axios.get(image.image).then((res) => {
          let blob = new Blob([res.data], {
            type: 'image/png',
          });
          blob.lastModifiedDate = new Date();
          let file = new File(
            [blob],
            getImageName(image.image),
            { type: 'image/png' }
          );
          file.preview = image.image;
          return file;
        })
      )
    ).then((images) => setFiles(images));