Handling File Uploads
In this page:
Reading a Selected File's Info
A file input's onChange handler receives an event whose target.files is a FileList containing the chosen file(s). Even without uploading anything, you can immediately read the file's name, size, and type from this object.
Note: files[0] gets the first (or only, for a non-multiple input) selected file.
Warning: e.target.files is empty if the user cancels the file picker dialog — always check files.length before accessing files[0].
Example: Reading a Selected File's Info
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function App() {
const [fileName, setFileName] = React.useState("");
const handleChange = e => {
const file = e.target.files[0];
setFileName(file ? file.name : "No file selected");
};
return <div><input type="file" onChange={handleChange} /><p>{fileName}</p></div>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>
Previewing an Image Before Upload
URL.createObjectURL(file) generates a temporary local URL pointing directly at the selected file's data, letting you show an <img> preview instantly without needing to upload it to a server first.
Note: Revoke the object URL with URL.revokeObjectURL() when it's no longer needed, to free up browser memory.
Warning: Object URLs only work for as long as the page is open — they can't be saved or shared as permanent links.
Example: Previewing an Image Before Upload
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function App() {
const [preview, setPreview] = React.useState(null);
const handleChange = e => {
const file = e.target.files[0];
if (file) setPreview(URL.createObjectURL(file));
};
return (
<div>
<input type="file" accept="image/*" onChange={handleChange} />
{preview && <img src={preview} width="100" />}
</div>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>
Why File Inputs Are Always Uncontrolled
Browsers don't allow JavaScript to set a file input's value, as a security measure to stop websites from pretending files were chosen by the user. Because of this, file inputs never take a value prop in React — you can only read what the user picked, via onChange or a ref.
Note: To clear a file input, reset it via a ref (inputRef.current.value = '') rather than trying to control it with state.
Warning: Attempting input.value = 'somefile.png' throws a security error in every modern browser — this is a hard, unavoidable browser restriction.
Example: Why File Inputs Are Always Uncontrolled
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function App() {
const inputRef = React.useRef(null);
const clearFile = () => { inputRef.current.value = ""; };
return (
<div>
<input type="file" ref={inputRef} />
<button onClick={clearFile}>Clear Selection</button>
</div>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>
- Trying to set a file input's value directly, which browsers block for security reasons.
- Forgetting that e.target.files is a FileList, not a plain array — needing Array.from() or indexing.
- Not showing any feedback (file name, preview, progress) after a file is chosen, leaving users unsure it worked.
- File inputs are always uncontrolled in React — you can't set their value programmatically.
- The onChange event's e.target.files gives you a FileList of the selected file(s).
- You can read file metadata (name, size, type) immediately, without uploading anything.
- FileReader or URL.createObjectURL can generate an image preview before the file is sent to a server.
No React-version restriction — relies on the standard File/FileReader Web APIs, supported in all modern browsers.
Chapter Quiz — Complete all 8 topics to unlock
0/8 topics done
Complete these topics first: