React 18 Multiple Files Upload with Express REST API Tutorial

Last Updated on by in React JS
We are going to discuss mostly talked about topic React Multiple Files Upload with Node/Express Js.In this tutorial, we are going to learn how to upload multiple image files using REST APIs built with Node, Express, Multer, and MongoDB.

If you are new to React and want to learn how to upload files, then follow along.

We will help you learn to upload multiple image files and store those files in the MongoDB database using Multer and React.

To create the React multiple file upload component, we will create express REST API which a user can easily use to make a POST request using React Axios.

React 18 Multiple Files Upload using Express REST API Example

Let’s, install React app for uploading multiple files .

Install React Framework

Run command from your terminal to install the brand new React js application.

npx create-react-app react-multiple-files-upload

Go to the project folder:

cd react-multiple-files-upload

Install and set up Bootstrap 5 in functional component:

npm install bootstrap --legacy-peer-deps

Include bootstrap.min.css in src/App.js file:

import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

Create Component File

Navigate to src/components folder and create files-upload-component.js file here.

import React from "react";

export default function FilesUploadComponent() {
  return (
    <div className="container">
      <form>
        <div className="mb-3">
          <input type="file" multiple />
        </div>

        <button className="btn btn-primary" type="submit">
          Upload
        </button>
      </form>
    </div>
  );
}

Include FilesUploadComponent in src/App.js file.

import React from "react";
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import "./App.css";
import FilesUploadComponent from "./components/files-upload-component";

function App() {
  return (
    <div className="w-50 p-3">
      <FilesUploadComponent />
    </div>
  );
}

export default App;

React Multiple Files Upload

Create Multiple File Upload APIs

First, you have to create the backend folder at the root of your React app.

Create specific package.json file for Node server.

npm init -y

Install essential NPM packages using the given command:

npm install mongoose express cors body-parser uuid@^3.3.3 multer --legacy-peer-deps

Install nodemon package to restart the node server automatically. If any change occurs in server files.

npm install nodemon --save-dev --legacy-peer-deps

Create Mongoose Schema

Create backend > models folder and create User.js file in it.

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
    _id: mongoose.Schema.Types.ObjectId,
    imgCollection: {
        type: Array
    }
}, {
    collection: 'users'
})

module.exports = mongoose.model('User', userSchema)

Define imgCollection value with Array data type with Mongoose _id.

Build Express Routes

Create backend > routes directory and create user.routes.js file in it.

let express = require('express'),
    multer = require('multer'),
    mongoose = require('mongoose'),
    uuidv4 = require('uuid/v4'),
    router = express.Router();

const DIR = './public/';

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, DIR);
    },
    filename: (req, file, cb) => {
        const fileName = file.originalname.toLowerCase().split(' ').join('-');
        cb(null, uuidv4() + '-' + fileName)
    }
});

var upload = multer({
    storage: storage,
    fileFilter: (req, file, cb) => {
        if (file.mimetype == "image/png" || file.mimetype == "image/jpg" || file.mimetype == "image/jpeg") {
            cb(null, true);
        } else {
            cb(null, false);
            return cb(new Error('Only .png, .jpg and .jpeg format allowed!'));
        }
    }
});

// User model
let User = require('../models/User');

router.post('/upload-images', upload.array('imgCollection', 6), (req, res, next) => {
    const reqFiles = [];
    const url = req.protocol + '://' + req.get('host')
    for (var i = 0; i < req.files.length; i++) {
        reqFiles.push(url + '/public/' + req.files[i].filename)
    }

    const user = new User({
        _id: new mongoose.Types.ObjectId(),
        imgCollection: reqFiles
    });

    user.save().then(result => {
        res.status(201).json({
            message: "Done upload!",
            userCreated: {
                _id: result._id,
                imgCollection: result.imgCollection
            }
        })
    }).catch(err => {
        console.log(err),
            res.status(500).json({
                error: err
            });
    })
})

router.get("/", (req, res, next) => {
    User.find().then(data => {
        res.status(200).json({
            message: "User list retrieved successfully!",
            users: data
        });
    });
});

module.exports = router;

We have to create public folder at the root of the backend/ folder; this is the place where we are going to keep all the uploaded image files.

Main Server File Setup

Next, create index.js file inside backend folder and paste the given below code inside of it.

let express = require("express"),
  mongoose = require("mongoose"),
  cors = require("cors"),
  bodyParser = require("body-parser");

const api = require("../backend/routes/user.routes");

// Connecting mongoDB Database
mongoose
  .connect("mongodb://127.0.0.1:27017/test")
  .then((x) => {
    console.log(
      `Connected to Mongo! Database name: "${x.connections[0].name}"`,
    );
  })
  .catch((err) => {
    console.error("Error connecting to mongo", err.reason);
  });

const app = express();
app.use(bodyParser.json());
app.use(
  bodyParser.urlencoded({
    extended: false,
  }),
);
app.use(cors());

app.use("/public", express.static("public"));

app.use("/api", api);

const port = process.env.PORT || 4000;
const server = app.listen(port, () => {
  console.log("Connected to port " + port);
});

app.use((req, res, next) => {
  // Error goes via `next()` method
  setImmediate(() => {
    next(new Error("Something went wrong"));
  });
});

app.use(function (err, req, res, next) {
  console.error(err.message);
  if (!err.statusCode) err.statusCode = 500;
  res.status(err.statusCode).send(err.message);
});

Test React Multiple Files Upload API

In this step we will test REST API which we just created, before that we need to start the Node server.

Follow the given below process to start the Node/Express server.

Check out how to install MongoDB community edition on your local machine.

Run nodemon server by executing the following command:

npx nodemon server
Method API URL
GET http://localhost:4000/api
POST /api/upload-images

API base Url: http://localhost:4000/api

Final API result:

Upload API Testing

Create React Multiple Images Upload

Let’s create React multiple image files uploading functionality in React. We need to install axios.

npm install axios --legacy-peer-deps

Insert following code in src/components/files-upload.component.js file.

import React, { Component } from 'react';
import axios from 'axios';

export default class FilesUploadComponent extends Component {

    constructor(props) {
        super(props);

        this.onFileChange = this.onFileChange.bind(this);
        this.onSubmit = this.onSubmit.bind(this);

        this.state = {
            imgCollection: ''
        }
    }

    onFileChange(e) {
        this.setState({ imgCollection: e.target.files })
    }

    onSubmit(e) {
        e.preventDefault()

        var formData = new FormData();
        for (const key of Object.keys(this.state.imgCollection)) {
            formData.append('imgCollection', this.state.imgCollection[key])
        }
        axios.post("http://localhost:4000/api/upload-images", formData, {
        }).then(res => {
            console.log(res.data)
        })
    }

    render() {
        return (
            <div className="container">
                <div className="row">
                    <form onSubmit={this.onSubmit}>
                        <div className="form-group">
                            <input type="file" name="imgCollection" onChange={this.onFileChange} multiple />
                        </div>
                        <div className="form-group">
                            <button className="btn btn-primary" type="submit">Upload</button>
                        </div>
                    </form>
                </div>
            </div>
        )
    }
}

Run the app with the help of the following command and check the app on the browser:

npm start

View project on this URL: localhost:3000

React multiple files upload

Conclusion

Finally, React Multiple File Upload with Node/Express Tutorial is over. In this tutorial, we explored how to upload a multiple image files in the MongoDB database using the Node and Express server.

Git Repo

Digamber - Author positronX.io

Hi, I'm Digamber Singh, a New Delhi-based full-stack developer, tech author, and open-source contributor with 10+ years' experience in HTML, CSS, JavaScript, PHP, and WordPress.