Author avatar

Gaurav Singhal

How to Use a Simple Form Submit with Files in React

Gaurav Singhal

  • Jun 29, 2020
  • 5 Min read
  • 171,056 Views
  • Jun 29, 2020
  • 5 Min read
  • 171,056 Views
Web Development
Front End Web Development
Client-side Framework
React

Introduction

Uploading images or files is a major function of any app. It is an essential requirement for creating a truly full-stack app. For example, Facebook, Instagram, and Snapchat all have the functionality to upload images and videos.

In traditional HTML sites, the file upload form forces a page refresh, which might be confusing to users. Also, you might want to customize the look of the file input in the form to make it resonate with your overall app design. When it comes to both of these issues, React can help you provide a better user experience.

This guide will get you up and running with file uploads in React.

Creating a Basic Form

In your App.js file, create a basic form that with a name field and a file input.

1import React from "react";
2
3const App = () => {
4  return (
5    <div className="App">
6      <form>
7        <input type="text" />
8
9        <input type="file" />
10      </form>
11    </div>
12  );
13};
jsx

Now, add state in the component to store the name and the file data.

1import React, { useState } from "react";
2
3const App = () => {
4  const [name, setName] = useState("");
5  const [selectedFile, setSelectedFile] = useState(null);
6  return (
7    <div className="App">
8      <form>
9        <input
10          type="text"
11          value={name}
12          onChange={(e) => setName(e.target.value)}
13        />
14
15        <input
16          type="file"
17          value={selectedFile}
18          onChange={(e) => setSelectedFile(e.target.files[0])}
19        />
20      </form>
21    </div>
22  );
23};
jsx

Creating a Custom File Uploader Component

Now that the basic form is set up, create a custom file uploader component that can be reused across multiple forms in the app.

If you check the output of the current form, you will notice that the file input doesn't have a great look; that's because the browser defines its default styling. In this section, you will learn how to create a file upload component with custom styling.

1const FileUploader = () => {
2    const handleFileInput = () => {}
3
4    return (
5        <div className="file-uploader">
6            <input type="file" onChange={handleFileInput}>
7        </div>
8    )
9}
jsx

To create a custom file uploader, the first step is to hide the default input and trigger the change event using a ref.

1import React, {useRef} from 'react'
2
3const FileUploader = ({onFileSelect}) => {
4    const fileInput = useRef(null)
5
6    const handleFileInput = (e) => {
7        // handle validations
8        onFileSelect(e.target.files[0])
9    }
10
11    return (
12        <div className="file-uploader">
13            <input type="file" onChange={handleFileInput}>
14            <button onClick={e => fileInput.current && fileInput.current.click()} className="btn btn-primary">
15        </div>
16    )
17}
jsx

You can style the upload button to match the theme of your overall application. Send the uploaded file back to the parent component using a callback prop; in this case, it is onFileSelect. Inside the handleFileInput method, you can do validations like checking for filesize, file extensions, etc., and based on that, send feedback to the parent component using callback props like onFileSelectSuccess and onFileSelectError.

1const handleFileInput = (e) => {
2  // handle validations
3  const file = e.target.files[0];
4  if (file.size > 1024)
5    onFileSelectError({ error: "File size cannot exceed more than 1MB" });
6  else onFileSelectSuccess(file);
7};
jsx

Adding the File Uploader Component to the Form

Add the file uploader component as follows :

1import React, { useState } from "react";
2
3const App = () => {
4  const [name, setName] = useState("");
5  const [selectedFile, setSelectedFile] = useState(null);
6
7  const submitForm = () => {};
8
9  return (
10    <div className="App">
11      <form>
12        <input
13          type="text"
14          value={name}
15          onChange={(e) => setName(e.target.value)}
16        />
17
18        <FileUploaded
19          onFileSelectSuccess={(file) => setSelectedFile(file)}
20          onFileSelectError={({ error }) => alert(error)}
21        />
22
23        <button onClick={submitForm}>Submit</button>
24      </form>
25    </div>
26  );
27};
jsx

Uploading Files Using FormData

Upload a selected file using the FormData object. Append the name and file using the append method of the formData object.

1const submitForm = () => {
2  const formData = new FormData();
3  formData.append("name", name);
4  formData.append("file", selectedFile);
5
6  axios
7    .post(UPLOAD_URL, formData)
8    .then((res) => {
9      alert("File Upload success");
10    })
11    .catch((err) => alert("File Upload Error"));
12};
jsx

That's pretty much it. You have successfully created and added a custom file upload component.

Conclusion

File uploading is an essential part of any web app. You can use other third-party libraries to create custom file upload inputs, but you should have a fair idea of how they are implemented under the hood.

There are several instances where file uploads are required, but with some customization. Third-party libraries may not always help you out in such cases, however, your custom file upload utility can.