There are a number of different ways you can upload files for storage from a React application. In this tutorial we’ll be using Node.js with Express, and Multer a middleware for handling multipart form data.
Before beginning you’ll need to have Node.js installed which can be done by following the instructions on the offical website.
Building the React frontend
We’ll start by setting up the project using Create React App and installing axios a promise based HTTP client that simplifies API requests. Open a terminal window and run the following commands:
npx create-react-app file-upload
cd file-upload
npm install axios
Create a new file called FileUpload.js
and we can get started with the code.
First import React
, { useState }
as we’ll store file data in state, and axios
:
import React, { useState } from "react";
import axios from "axios";
Then add a FileUpload()
function that contains a simple file upload form:
function FileUpload() {
return (
<form onSubmit={uploadFile}>
<input type="file" name="file" onChange={getFile} required />
<input type="submit" name="upload" value="Upload" />
</form>
);
}
export default FileUpload;
Next still inside the FileUpload()
function we’ll add the functionality for when the onChange
event is triggered. We first declare a variable for the fileData
then when the function is called save the data using setFileData
:
const [fileData, setFileData] = useState("");
const getFile = (e) => {
setFileData(e.target.files[0]);
};
Complete the FileUpload()
function by adding the code to handle the onSubmit
event:
const uploadFile = (e) => {
e.preventDefault();
const data = new FormData();
data.append("file", fileData);
axios({
method: "POST",
url: "http://localhost:5000/upload",
data: data,
}).then((res) => {
alert(res.data.message);
});
};
This will POST
the data from fileData
to our Node.js endpoint at http://localhost:5000/upload
and once complete alert a response with the status of the upload.
Complete the frontend by loading the component into App.js
as follows:
import React from 'react';
import FileUpload from "./FileUpload";
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<FileUpload />
</header>
</div>
);
}
export default App;
If you run the npm run start command you should see the following in the browser:
Building the Node.js backend
For the backend we’ll need to install the following Node.js dependencies:
npm install express cors multer
express
– used to create the endpoint (URI) for the POST request.cors
– allows the frontend and backend to share resources.multer
– middleware for handling the file uploads.
We’ll also install nodemon
as a dev dependency to monitor the server for file changes so a restart isn’t required on each code update:
npm install nodemon --save-dev
Next create a server.js
file, include the dependencies, and define the app:
const express = require("express");
const multer = require("multer");
const cors = require("cors");
const app = express();
app.use(cors());
The only config required for multer
is to specify the folder in which our files will be saved. Here we’ll save them to a /uploads
folder in the /public
directory so they can be accessed by the frontend if required:
var upload = multer({ dest: "../public/uploads/" });
Now we’ll handle the POST
request.
If file data upload the file, otherwise no file was found, or a server error occurred:
app.post("/upload", upload.single("file"), async (req, res) => {
try {
if (req.file) {
res.send({
status: true,
message: "File Uploaded!",
});
} else {
res.status(400).send({
status: false,
data: "File Not Found :(",
});
}
} catch (err) {
res.status(500).send(err);
}
});
Finally let’s tell the app to listen to port 5000:
app.listen(5000, () => console.log("Server Running..."));
Start the server with the following command and then we can test the form:
nodemon server.js
If the file upload was successful you’ll get a “File Uploaded!” alert message. You can double check the upload was successful by browsing the public/uploads
folder. If the upload failed check the server console for more details.