React upload multiple files

We can upload multiple files in React by using a mix of FormData() interface and the Fetch API.

For this example, we want to build React app that uploads a few files and shows a busy indicator the files are sent to the server. I've made this video with the completed example:

And here is the full code for it:

const API_URL = 'https://httpbin.org/post'
const API_METHOD = 'POST'
const STATUS_IDLE = 0
const STATUS_UPLOADING = 1

const App = () => {
    const [files, setFiles] = React.useState([])
    const [status, setStatus] = React.useState(STATUS_IDLE)

    const uploadFiles = (data)=> {
        setStatus(STATUS_UPLOADING);

        fetch(API_URL, {
            method: API_METHOD,
            body: data,
        })
        .then((res) => res.json())
        .then((data) => console.log(data))
        .catch((err) => console.error(err))
        .finally(() => setStatus(STATUS_IDLE))
    }

    const packFiles = (files)=> {
        const data = new FormData();

        [...files].forEach((file, i) => {
            data.append(`file-${i}`, file, file.name)
        })
        return data
    }

    const handleUploadClick = () => {
        if (files.length) {
            const data = packFiles(files)
            uploadFiles(data)
        }
    }

    const renderFileList = () => (<ol>
        {[...files].map((f, i) => (
            <li key={i}>{f.name} - {f.type}</li>
        ))}
    </ol>)

    const renderButtonStatus = () => (
        (status === STATUS_IDLE) ? 
            'Send to server' : 
            <img src = "./load.svg" />
    )

    return (<div>
        <input
            type="file"
            accept="image/*" 
            multiple
            onChange={(e)=> setFiles(e.target.files)} />
        {renderFileList()}
        <button onClick={handleUploadClick} disabled={status === STATUS_UPLOADING}>
            {renderButtonStatus()}
        </button>
    </div>)
}

The whole magic of the example happens in packFiles(), where we use the FormData.append() method to wrap all the files into one single entity that is sent via a fetch request.

If you want to dive more into the FormData interface I've written two articles about it: a basic intro for fetch() and FormData and one that goes more into details about FormData and the append() method.

We are using the HttpBin service as a dummy endpoint placeholder. After receiving the request it just outputs back a JSON object where we can see the uploaded items in the files property.
React upload multiple files
The file uploader was customized so that it allows the section of multiple files and it takes only images as inputs. You can use the multiple and accept attributes to change these behaviors.
React upload multiple files

The actual files state variable is not an array, but it's iterable, so we can use the spread operator to get an array of files:

const renderFileList = () => (<ol>
  {[...files].map((f, i) => (
    <li key={i}>{f.name} - {f.type}</li>
  ))}
</ol>)

As a final note, you can use the URL.createObjectURL() to make image previews for the uploaded files.

You can see here the GitHub repo for this example, and here is the live working app.

📖 50 Javascript, React and NextJs Projects

Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.

📖 50 Javascript, React and NextJs Projects

Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.


Leave a Reply

Your email address will not be published. Required fields are marked *

Home Screencasts Best of Newsletter Search X

📖 50 Javascript, React and NextJs Projects

Hi friend! Before you go, just wanted to let you know about the 50 Javascript, React and NextJs Projects FREE ebook.

One of the best ways to learn is by doing the work. Choose from 8 project categories and get started right away:

  • Business & Real-World
  • Games & Puzzles
  • Fun & Interesting
  • Tools & Libraries
  • Personal & Portfolio
  • Project Add-Ons
  • Productivity
  • Clones

Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects complete with project briefs and wireframes!

Keep building and level up! Get all projects as an ebook right to your inbox!

X