Uploading files can be both tricky and easy. Let's say a user wants to upload images to the API REST endpoint. We'll use axios to make our http calls easy, (communicate with the API)
Axios is a promised based HTTP client for browser and node js. it's more the same as Fetch API. We do love axios because it works across all browsers and ease of transforming JSON data.
Next we'll create the user interface input to take the users input. We can either do this with the normal html or use something else. I'm a big fun of user experiences, and I want users to interact with the systems I make. So let's use react-dropzone
React-dropzone is a simple React hook to create a HTML5-compliant drag'n'drop zone for files.
Awesome Flexibility and extensibility
The ability to expand the props and methods on the file upload. This include props such as multiple file upload, file size, disabled, accept types of files, etc. Event methods include onDragEnter, onDrop, onFileDialogCancel, etc.
user-input(step by step explanation below)
import React from 'react'
import { useDropzone } from 'react-dropzone'
function MyDropzone() {
const {getRootProps, getInputProps} = useDropzone()
return (
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
)
}
with added styling, you'll end up with something like this
Definitions of Terms
useDropzone
hook just binds the necessary handlers to create a drag 'n' drop zone.getRootProps()
function is used to get the props required for drag 'n' drop and use them on any element.getInputProps()
function is used for click and keydown behavior, and use the returned props on an . The drag'n'drop useDropZone hook support file-selector, that convert a DragEvent or file input to a list of File objects
Let's extend the above codebase to send data to an API REST call. We'll introduce another prop in the useDropzone hook called acceptedFiles. this will hold all files uploaded as array.
import React from 'react'
import { useDropzone } from 'react-dropzone'
import axios from 'axios'
function MyDropzone() {
const {getRootProps, getInputProps, acceptedFiles} = useDropzone()
// make api call
const handleSubmit = () => {
axios.post('/submit-files', acceptedFiles[0]).then(file => {
console.log(file)
}).catch(error => console.log(error))
}
return (
<>
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
<button type="button" onClick={handleSubmit}>Upload File</>
</>
)
}
image preview
With React-dropzone, image preview is easy, just introduce thumbnails. This can be achived onDrop() callback function.
function Previews(props) {
const [files, setFiles] = useState([]);
const {getRootProps, getInputProps} = useDropzone({
accept: 'image/*',
onDrop: acceptedFiles => {
setFiles(acceptedFiles.map(file => Object.assign(file, {
preview: URL.createObjectURL(file)
})));
}
});
const thumbs = files.map(file => (
<div style={thumb} key={file.name}>
<div style={thumbInner}>
<img
src={file.preview}
style={img}
/>
</div>
</div>
));
useEffect(() => () => {
// Make sure to revoke the data uris to avoid memory leaks
files.forEach(file => URL.revokeObjectURL(file.preview));
}, [files]);
return (
<section className="container">
<div {...getRootProps({className: 'dropzone'})}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
<aside style={thumbsContainer}>
{thumbs}
</aside>
</section>
);
}
React-dropzone Docs
React-dropzone documentation has good style guide to every developer, new or experienced. There are awesome examples, code samples, reference and explanation on how everything works in relation with files. So check out more react-dropzone.js.org