Create Button from each item in array React

I am working with Unsplash API and I am trying to get the images to download. I can get them to download, however it downloads every single photo instead of just the one I want when I use a for loop. If I remove the saveAs part outside of the loop it only downloads the final image in the array instead of the others no matter what button I click. Here is my code:

import React, { useState, useEffect } from 'react';
import { Heading } from './components/Heading';
import { Loader } from './components/Loader';
import { UnsplashImage } from './components/UnsplashImage';
import InfiniteScroll from 'react-infinite-scroll-component';
import { saveAs } from 'file-saver';


import axios from 'axios';
import styled from 'styled-components';
import { createGlobalStyle } from 'styled-components';
import SearchPhotos from './components/searchPhotos';
import Heart from './components/Heart';
import { FileUpload } from './components/Upload';

const GlobalStyle = createGlobalStyle`
  *{
    margin: 0px;
    padding: 0px;
    box-sizing: border-box;
  }

  body{
    font-family: sans-serif;
  }
`;

const WrapperImg = styled.section`
  max-width: 70rem;
  margin: 4rem auto;
  display: grid;
  grid-gap: 1em;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
`;

const H1 = styled.h1`
  max-width: 70rem;
  margin: 4rem auto;
`;

const Div = styled.div`
  display: flex;
  flex-direction: column;
  margin-bottom: 2rem;
  height: auto;
  width: 100%;
  position: relative;
`;


function App() {
  const [images, setImages] = useState([]);

  useEffect(() => {
    fetchImages();
  }, [])

  const fetchImages = () => {
    const apiURL = "https://api.unsplash.com";
    const apiKey = "MY_KEY_";
    axios
      .get(`${apiURL}/photos/random?client_id=${apiKey}&count=1`)
      .then(res => setImages([...images, ...res.data]))
  }

  const imgURL = images.map((download) => {
    //console.log(download.urls.full)
    return download.urls.full;
  });

  const Download = () => {
    const downloadImage = () => {
      for (var i = 0; i < imgURL.length; i++) {
        var red = imgURL[i];
        //saveAs(red, 'image.jpg');
        console.log(red);
      } 
      //saveAs(red, 'image.jpg');

    }
    return <button onClick={downloadImage}>Download</button>
  }

  return (
    <div className="App">
      <Heading />
      <GlobalStyle />
      <SearchPhotos />
      <InfiniteScroll
        dataLength={images.length}
        next={fetchImages}
        hasMore={true}
        loader={<Loader />}
      >
        <H1>Main Feed:</H1>
        <WrapperImg>
          <FileUpload />
          {images.map(image =>
          (<>
            <Div>
              <Heart />
              <UnsplashImage url={image.urls.thumb} key={image.id} />
              <p className="like"> Amount of Likes ❤️ {image.likes}</p>
              <Download />
            </Div>
          </>))}
        </WrapperImg>
      </InfiniteScroll>
    </div>
  );
}

export default App;

>Solution :

Try this to download each image, I have removed loop and modified the Download function

  const imgURL = images.map((download) => {
    //console.log(download.urls.full)
    return download.urls.full;
  });

    const downloadImage = (index) => {
       var red = imgURL[index];
        saveAs(red, 'image.jpg');    
    }


  return (
    <div className="App">
        <WrapperImg>
          {images.map((image,index) =>
          (<>
            <Div>
              <UnsplashImage url={image.urls.thumb} key={image.id} />
              <button onClick={()=> { downloadImage(index) }>Download</button>
            </Div>
          </>))}
        </WrapperImg>
    </div>
  );
}

Leave a Reply