Ever implemented an upload file feature with React and you try using an npm package but the package doesn’t have options for selecting multiple images? In this tutorial, we will solve that challenge by implementing a simple React app where users can select multiple images.
Prerequisites
- Knowledge of JavaScript and React basics
- Node >=v14 installed
The complete project is here on Codesandbox.
Getting Started
Let’s start by bootstrapping a new react project with create-react-app. Run the command below to do this:
1#bash2npx create-react-app upload-multiple-images
When it’s done installing, run these commands in your terminal to start the React app.
1#bash2cd upload-multiple-images3npm run start
The app should start at http:localhost:3000
.
Navigate to the src
directory and delete all the files except index.js
, App.js
, and index.css
. This would break the react app that’s running but don’t worry we’ll fix that soon.
Update the index.js
with the code snippet below:
1//index.js2import React from 'react';3import ReactDOM from 'react-dom/client';4import './index.css';5import App from './App';67const root = ReactDOM.createRoot(document.getElementById('root'));8 root.render(9 <React.StrictMode>10 <App />11 </React.StrictMode>12 );
In this project, we’ll be using react-bootstrap
components, so head to your terminal and run the following commands to install the packages.
1#bash2npm install react-bootstrap bootstrap
If you’ve gotten up to this point, you’re awesome!
Creating Mock data
For this project, we’ll be using some mock images to demonstrate multiple selections. Go ahead and create a mock.js
file at the root directory.
Paste this code snippet in mock.js
.
1//mock.js23export const mockData = [4 {5 src: "https://images.unsplash.com/photo-1653325532801-20505a866e9d?crop=entropy&cs=tinysrgb&fm=jpg&ixlib=rb-1.2.1&q=80&raw_url=true&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=387",6 },7 {8 src: "https://images.unsplash.com/photo-1534353436294-0dbd4bdac845?crop=entropy&cs=tinysrgb&fm=jpg&ixlib=rb-1.2.1&q=80&raw_url=true&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=387",9 },10 {11 src: "https://images.unsplash.com/photo-1471897488648-5eae4ac6686b?crop=entropy&cs=tinysrgb&fm=jpg&ixlib=rb-1.2.1&q=80&raw_url=true&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=387",12 },13 {14 src: "https://images.unsplash.com/photo-1653325297180-2ba1b7e34215?crop=entropy&cs=tinysrgb&fm=jpg&ixlib=rb-1.2.1&q=80&raw_url=true&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=379",15 },16 {17 src: "https://images.unsplash.com/photo-1652534603944-2ebdf360d6c7?crop=entropy&cs=tinysrgb&fm=jpg&ixlib=rb-1.2.1&q=80&raw_url=true&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=725",18 },19 {20 src: "https://images.unsplash.com/photo-1653349859617-48672bdfa490?crop=entropy&cs=tinysrgb&fm=jpg&ixlib=rb-1.2.1&q=80&raw_url=true&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=423",21 },22 {23 src: "https://images.unsplash.com/photo-1653356677409-27ecda2dcba4?crop=entropy&cs=tinysrgb&fm=jpg&ixlib=rb-1.2.1&q=80&raw_url=true&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=387",24 },25 {26 src: "https://images.unsplash.com/photo-1653359406652-843d58aec2c8?crop=entropy&cs=tinysrgb&fm=jpg&ixlib=rb-1.2.1&q=80&raw_url=true&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=387",27 },28 {29 src: "https://images.unsplash.com/photo-1653376774810-a81964615abb?crop=entropy&cs=tinysrgb&fm=jpg&ixlib=rb-1.2.1&q=80&raw_url=true&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=391",30 }31]
Now we’ve created our mock data, let’s go ahead and make use of the data in our App
component.
Implementing Component UI
Let’s create a simple image grid UI.
Navigate to App.js
and add the code snippet below:
1//App.js23import 'bootstrap/dist/css/bootstrap.min.css';4import { Container, Col, Row, Image } from 'react-bootstrap'5import { mockData } from './mock';67function App() {8 const handleClick = () => { }9return (10 <Container>11 <Row>12 {mockData.map((data, index) => (13 <Col md={4} key={index} >14 <div className="img-card" onClick={() => handleClick(data.src)}>15 <Image style={{ width: '300px', height: "300px" }} thumbnail src={data.src} />16 </div>17 </Col>18 )19 )}20 </Row>21 </Container>22);23}24export default App;
Let’s break down the code snippet into chunks.
First, we import bootstrap css so we can use bootstrap styles with our react-bootstrap
components.
Next, we import react-bootstrap components, and we use them in the template.
We also imported the mock data and used it in templates.
There’s also a handleClick()
function we’ll work on in the next section.
Let’s also some custom css styles. Go to index.css
and add these lines of code:
1//index.css23body {4 margin: 0;5 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',6 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',7 sans-serif;8 -webkit-font-smoothing: antialiased;9 -moz-osx-font-smoothing: grayscale;10}1112.img-checked {13 padding: 10px;14 width: 300px;15 background: rgb(49, 132, 199);16 color: white;17 border-radius: 20px;18 font-weight: bolder;19 position: relative;20 /* margin-top: 2px ; */21}22.img-card{23 border: 3px solid rgb(95, 95, 95);24 margin: 10px;25 width: 300px;26}27.img-card:hover {28 border: 2px solid red;29}
Run the app with npm run start
and navigate to your browser. You should have something like this:
Awesome. Let’s now go ahead to implement select functionality.
Implementing Multiple Select Functionality
After displaying the image gallery, we will create a hover event for marking images that will be uploaded. Navigate to the App``.js
file and update with the following lines of code.
1//App.js2...3import { useState } from 'react'4...56function App() {7 const [allImages, setAllImages] = useState([]);8 const handleClick = async (source) => {9 const check = allImages.includes(source)10 if (check) {11 const id = allImages.indexOf(source)12 let newArr = allImages13 newArr.splice(id, 1)14 setAllImages([...newArr])15 } else {16 allImages.push(sourc)17 setAllImages([...allImages])18 }19 }2021return (22 ...23 <div className="img-card" onClick={() => handleClick(data.src)}>24 ....25 {allImages.includes(data.src) ?26 <div className="img-checked" >Selected</div>27 : null}28 </div>29)30}
The above code snippets include some state variables.
- allImages: This is an array of the selected images.
- handleClick: This function handles the
onClick
event when adding an image to the list.
We wrapped our image tag with a div that has an on hover event, such that a border appears on hover. We then display a text selected when an image is selected.
We then implemented the handleClick
function.
The function handles the onClick event. It checks if the value passed exists in the mock**D**ata ****array; if so, it pops the value from the array. If not, it pushes the value into the array.
Go ahead save and run the app on your terminal. You should see something like this:
We can now upload the array of images to an external platform or an upload media API endpoint.
Conclusion
In this tutorial, we learned how to build a React application that handles multiple image uploads with React Bootstrap.