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'))