All topics
Formsintermediate

File Uploads in React

Learn how to handle file input, previews, and multipart upload requests in a React form.

File inputs (<input type="file">) are inherently uncontrolled in React, since browsers don't allow JavaScript to programmatically set a file input's value for security reasons — you read the selected file(s) via the input's files property (accessed through a ref or directly from the change event's event.target.files), rather than driving it with a value prop like other form fields.

A file input is like a physical mail slot where the browser (not you) decides what letter gets dropped in — you can look at what arrived and describe it to others, but you can't reach in and swap the letter yourself; sending it onward via FormData is like properly boxing and labeling that physical letter for shipping, rather than trying to fax a photograph of it (JSON) instead.

Key Concepts

1
A common UX addition is generating a local preview of an uploaded image before it's sent anywhere, using URL.createObjectURL(file) to create a temporary local URL pointing at the in-memory file data, which can be set as an <img src> directly — this preview works entirely client-side without needing to upload the file first. Object URLs should be explicitly revoked with URL.revokeObjectURL() when no longer needed (commonly in a cleanup effect) to avoid retaining memory for files the user has since replaced or the component has unmounted.
URL.createObjectURL(file)<img src>URL.revokeObjectURL()
2
Actually sending the file to a server almost always uses FormData, which correctly encodes file(s) and other field values as multipart/form-data, the content type file uploads require — appending the file object directly to a FormData instance and passing that as the fetch/axios request body handles the encoding correctly without manual base64 conversion in most cases.
FormDatamultipart/form-datafetchaxios
3
Interviewers ask candidates to implement a file input with a live image preview and explain both why file inputs must remain uncontrolled and why FormData (rather than JSON) is the correct vehicle for actually transmitting the file's binary content to a server.
FormData