react js handling file upload

If you are planning to upload files using node and express then you have to create both server and client. The server has the api and the client is going to use that for uploading the file with axios.

  • Server part

First, we want to put in four packages that are express, explicit-fileupload,cors and nodemon. Run the below command to install applications.

npm i express express-fileupload cors nodemon

Now open the fileupload folder in your favorite code editor and create a brand new document referred to as server.js.

// server.js
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');
})

use node server.js to start the server running.

  • Client

Open the react app folder on your favorite code editor and create a brand new report known as fileupload.js within the src folder. Now upload the following code.

// fileupload.js
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]; // accesing 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 video*/}
            {data.path && <video src={data.path} autoPlay controls />}
            </div>
        </div>
    );
}
export default FileUpload;

Now import the FileUpload component inside the App.js file.

// App.js
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.

For more: React File Upload Demo


You can make use of FileReader

var FormBox = React.createClass({
          getInitialState: function () {
            return {
              file: '',
              imagePreviewUrl: ''
            }
          },
          pressButton: function () {
            e.preventDefault();
          // TODO: do something with -> this.state.file
          console.log('handle uploading-', this.state.file);
          },
          getPhoto: function (e) {
            e.preventDefault();

            let reader = new FileReader();
            let file = e.target.files[0];

            reader.onloadend = () => {
              this.setState({
                file: file,
                imagePreviewUrl: reader.result
              });
            }

            reader.readAsDataURL(file);
            
          },
          render: function () {
            let {imagePreviewUrl} = this.state;
            let imagePreview = null;
            if (imagePreviewUrl) {
              imagePreview = (<img src={imagePreviewUrl} />);
            } else {
              imagePreview = (<div className="previewText">Please select an Image for Preview</div>);
            }
            return (
              <div>
              <form action='.' enctype="multipart/form-data">
                <input type='file'  onChange={this.getPhoto}/>
                <button onClick={this.pressButton}> Get it </button>
              </form>
              <div className="imgPreview">
                {imagePreview}
              </div>
              </div>
            )
          }
        })
        
        ReactDOM.render(<FormBox />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<div id="root"></div>

import axios from 'axios';
var FormBox = React.createClass({
  getInitialState: function () {
    return {
      photo: [],
      name : '',
      documents:[]
    }
  },
  pressButton: function () {
    var component = this
    var data = new FormData();
    data.append("photo", component.state.photo, component.state.name);
    var request = axios.post('http://localhost:3000/document', data)
        request.then(function(response){
    // you need to send data from server in response
          if(response.status == 200){
             console.log('saved in db')
             component.state.documents.push(response.data.documents)
             // pushed document data in documents array
           }
        })


  },
  getPhoto: function () {
    var uploadfile = document.getElementById(upload_doc).files[0]
    this.setState({
      photo: uploadfile, name : uploadfile.name
    })
  },
  render: function () {
    var documents = this.state.documents.map((doc)=>{
       return <div>
                <a href={doc.url}>{doc.name}</a>
                <img src={doc.photo} />
              </div>
    })
   // you can show your documents uploaded this way using map function
    return (
      <form action='.' enctype="multipart/form-data">
        <input type='file' id='upload_doc'  onChange={this.getPhoto}/>
        <button onClick={this.pressButton}> Get it </button>
        <span>{documents}</span>
        // this way you can see uploaded documents
      </form>
    )
  }
})

ReactDOM.render(<FormBox />, document.getElementById('root'))