How to Upload Files With React (2024)

How to Upload Files With React (1)

📣

If you're looking for a simple drop-in file upload component, check out Uppy.

Uploading a single file

To upload a single file in React, you need to set the content-type and content-length headers and provide the file contents as the request body:

import { ChangeEvent, useState } from 'react';function FileUploadSingle() { const [file, setFile] = useState<File>(); const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => { if (e.target.files) { setFile(e.target.files[0]); } }; const handleUploadClick = () => { if (!file) { return; } // 👇 Uploading the file using the fetch API to the server fetch('https://httpbin.org/post', { method: 'POST', body: file, // 👇 Set headers manually for single file upload headers: { 'content-type': file.type, 'content-length': `${file.size}`, // 👈 Headers need to be a string }, }) .then((res) => res.json()) .then((data) => console.log(data)) .catch((err) => console.error(err)); }; return ( <div> <input type="file" onChange={handleFileChange} /> <div>{file && `${file.name} - ${file.type}`}</div> <button onClick={handleUploadClick}>Upload</button> </div> );}export default FileUploadSingle;
  1. First, we add an input element with type="file" attribute.
  2. We can store the selected file in React component state, after receiving it from the onChange event. Since we're only able to select a single file, we can get it from the files array on the input: e.target.files[0].
  3. We can upload the file using the Fetch API. We need to set the set body to the file we received from the input and the headers: content-type to the file type and the content-length to file.size. Note that headers must be string values.

I used a httpbin.org API that accepts file uploads and responds with a copy of the request you send. Here's the result:

How to Upload Files With React (2)

Uploading files usually requires some work on the backend to accept, store, and serve those files upon request. If you'd like to learn that and more, I highly recommend educative.io courses.

Here's one that will help you master full-stack development with React:

How to Upload Files With React (4)

Uploading multiple files

To upload multiple files from input element in React, you need to use the FormData JavaScript API and encode the request as multipart/form-data.

import { ChangeEvent, useState } from 'react';function FileUploadMultiple() { const [fileList, setFileList] = useState<FileList | null>(null); const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => { setFileList(e.target.files); }; const handleUploadClick = () => { if (!fileList) { return; } // 👇 Create new FormData object and append files const data = new FormData(); files.forEach((file, i) => { data.append(`file-${i}`, file, file.name); }); // 👇 Uploading the files using the fetch API to the server fetch('https://httpbin.org/post', { method: 'POST', body: data, }) .then((res) => res.json()) .then((data) => console.log(data)) .catch((err) => console.error(err)); }; // 👇 files is not an array, but it's iterable, spread to get an array of files const files = fileList ? [...fileList] : []; return ( <div> <input type="file" onChange={handleFileChange} multiple /> <ul> {files.map((file, i) => ( <li key={i}> {file.name} - {file.type} </li> ))} </ul> <button onClick={handleUploadClick}>Upload</button> </div> );}export default FileUploadMultiple;

The first difference from our single file upload example is the addition of multiple attribute on the input element.

Instead of storing a single file in the React component state, we save the whole FileList in state

📣

Note that the FileList is not an array, so we can't use regular array methods like map or forEach. However, we can still access the members by index fileList[0], loop through the files using for..of or spread them.

To upload multiple files:

  1. Create a FormData object: const data = new FormData();
  2. Append each file you want to upload using FormData.append() - it accepts a form field name, the file, and a file name as parameters.
  3. Using the Fetch API, upload the files by setting form data as body. Note that when you use form data you don't need to set headers manually. It's taken care of by fetch API.

Here's what it looks like:

How to Upload Files With React (5)

Customizing the file input

The default input element doesn't offer much in terms of styling it. To create a custom file upload input in React, you will need to hide the native file upload input and trigger the click events on the input using refs:

import { ChangeEvent, useRef, useState } from 'react';function CustomFileInput() { const [file, setFile] = useState<File>(); const inputRef = useRef<HTMLInputElement | null>(null); const handleUploadClick = () => { // 👇 We redirect the click event onto the hidden input element inputRef.current?.click(); }; const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => { if (!e.target.files) { return; } setFile(e.target.files[0]); // 🚩 do the file upload here normally... }; return ( <div> <div>Upload a file:</div> {/* 👇 Our custom button to select and upload a file */} <button onClick={handleUploadClick}> {file ? `${file.name}` : 'Click to select'} </button> {/* 👇 Notice the `display: hidden` on the input */} <input type="file" ref={inputRef} onChange={handleFileChange} style={{ display: 'none' }} /> </div> );}

Only the input element with file type can open the files for selection in the browser. To upload a file when clicking the custom button, we need to trigger the click() event on the input: inputRef.current?.click();

If we don't want to show the native input, we can hide it by adding the display: none CSS property in it's style attribute or by applying a CSS class that sets the display property to none (e.g. in Tailwind, the class name is hidden).

From then on, you can save the selected files in state or upload them immediately. You now have full customization of the file upload input:

How to Upload Files With React (6)

Conclusion

In React file upload is implemented by using the HTML input element and some JavaScript to make a POST/PUT request to the server with the FormData that contains the selected files.

Your server will then need to process multipart form data to accept file uploads. You can use Multer in Node.js to implement that or upload the files directly to Amazon S3 if that's what you want.

You can find the code used in the examples in my GitHub repo.

Now that you know how to handle files on the front end you should also learn to handle them on the backend, I recommend this full-stack course on educative.io to help you do that:

Building Full-Stack Web Applications With Node.js and React - Learn Interactively

Node.js is a popular JavaScript runtime environment used to create server-side applications. It is an ideal tool for building robust, full-stack web applications with React. This course is an introduction to web development leveraging these two popular technologies. You’ll learn server-side applica…

How to Upload Files With React (7)Educative: Interactive Courses for Software Developers

How to Upload Files With React (8)

On this page

How to Upload Files With React (2024)
Top Articles
Latest Posts
Article information

Author: Duane Harber

Last Updated:

Views: 6566

Rating: 4 / 5 (51 voted)

Reviews: 90% of readers found this page helpful

Author information

Name: Duane Harber

Birthday: 1999-10-17

Address: Apt. 404 9899 Magnolia Roads, Port Royceville, ID 78186

Phone: +186911129794335

Job: Human Hospitality Planner

Hobby: Listening to music, Orienteering, Knapping, Dance, Mountain biking, Fishing, Pottery

Introduction: My name is Duane Harber, I am a modern, clever, handsome, fair, agreeable, inexpensive, beautiful person who loves writing and wants to share my knowledge and understanding with you.