How to upload files in React with NodeJS & Express
In this tutorial, we are going to learn about file uploading in React with using Express as a backend.
Creating Express Backend server
First, we are creating a post API using NodeJS & express, which helps us to upload the files like (images, pdf, etc) to the backend server.
Setup the backend project
Let’s setup the node.js backend project by running the following commands one by one.
mkdir fileupload
cd fileupload
npm init -y
Installing packages
Now, we need to install four packages which are express
, express-fileupload
,cors
and nodemon
.
Run the below command to install packages.
npm i express express-fileupload cors nodemon
Now open the fileupload
folder in your favorite code editor and create a new file called server.js
.
Add the following code to the server.js
file.
const express = require('express');
const fileUpload = require('express-fileupload');
const cors = require('cors')
const app = express();
// middle ware
app.use(express.static('public')); //to access the files in public folder
app.use(cors()); // it enables all cors requests
app.use(fileUpload());
// file upload api
app.post('/upload', (req, res) => {
if (!req.files) {
return res.status(500).send({ msg: "file is not found" })
}
// accessing the file
const myFile = req.files.file;
// mv() method places the file inside public directory
myFile.mv(`${__dirname}/public/${myFile.name}`, function (err) {
if (err) {
console.log(err)
return res.status(500).send({ msg: "Error occured" });
}
// returing the response with file path and name
return res.send({name: myFile.name, path: `/${myFile.name}`});
});
})
app.listen(4500, () => {
console.log('server is running at port 4500');
})
In the above code, we first imported three packages which are express
, express-fileupload
and cors
, next we created express application by invoking express()
function.
Our post API route is /upload
.
We are placing files inside the public
folder so that we need to create a public
folder inside our backend project.
Adding scripts
To run and restarting the server we are using the nodemon
, open your package.json
file and add the following code to scripts
object.
"server": "nodemon server.js"
Now start the backend server by running npm start server
command in your terminal.
Creating React App
Let’s create the new react app by running the following command.
npx create-react-app react-fileupload
Now change your current working directory by running the below command.
cd react-fileupload
Installing Axios library
We also need to install the axios http client library which is used to make the http requests.
npm i axios
Creating file upload component
Open the react-fileupload
folder in your favorite code editor and create a new file called fileupload.js
inside the src
folder.
Now add the following code.
import React, { useRef, useState } from 'react';
import axios from 'axios';
function FileUpload() {
const [file, setFile] = useState(''); // storing the uploaded file // storing the recived file from backend
const [data, getFile] = useState({ name: "", path: "" }); const [progress, setProgess] = useState(0); // progess bar
const el = useRef(); // accesing input element
const handleChange = (e) => {
setProgess(0)
const file = e.target.files[0]; // accessing file
console.log(file);
setFile(file); // storing file
}
const uploadFile = () => {
const formData = new FormData(); formData.append('file', file); // appending file
axios.post('http://localhost:4500/upload', formData, {
onUploadProgress: (ProgressEvent) => {
let progress = Math.round(
ProgressEvent.loaded / ProgressEvent.total * 100) + '%';
setProgess(progress);
}
}).then(res => {
console.log(res);
getFile({ name: res.data.name,
path: 'http://localhost:4500' + res.data.path
})
}).catch(err => console.log(err))}
return (
<div>
<div className="file-upload">
<input type="file" ref={el} onChange={handleChange} /> <div className="progessBar" style={{ width: progress }}>
{progress}
</div>
<button onClick={uploadFile} className="upbutton"> Upload
</button>
<hr />
{/* displaying received image*/}
{data.path && <img src={data.path} alt={data.name} />}
</div>
</div>
);
}
export default FileUpload;
In the above code, we have used react hooks to manage the state and we have two functions which are handleChange
and uploadFile
.
The handleChange
function is invoked once a user selected the file.
The uploadFile()
function is used to upload the file to our /upload
api.
There is also a progress bar, which shows the how much amount of file is uploaded to the server and also we are displaying the image
once a response
comes from the server.
Adding css styles
Add the following styles to your App.css
file.
.App {
margin: 2rem auto;
max-width: 800px;
}
img{
width: 500px;
height: 500px;
object-fit: contain;
}
.progessBar{
height: 1rem;
width: 0%;
background-color: rgb(68, 212, 231);
color: white;
padding:2px
}
.file-upload{
box-shadow: 2px 2px 2px 2px #ccc;
padding: 2rem;
display: flex;
flex-direction: column;
justify-content: space-between;
font-size: 1rem;
}
input , div , button{
margin-top: 2rem;
}
.upbutton{
width: 5rem;
padding: .5rem;
background-color: #2767e9;
color: aliceblue;
font-size: 1rem;
cursor: pointer;
}
Now, import the FileUpload
component inside the App.js
file.
import React from 'react';
import FileUpload from './fileupload';
import './App.css';
function App() {
return (
<div className="App">
<FileUpload />
</div >
);
}
export default App;
Start the react app by running npm start
.
Testing react file upload component
Let’s test our FileUpload
component by uploading a sample image file.
Note: Make sure that your backend server is on.
Open your browser and navigate to localhost:3000
.