Using it inside a form
Mirror accepted files into a hidden input so a native form submission includes them.
react-mediadrop’s files live in its own store, not in a native
<input type="file"> — a plain form submission won’t include them
unless you mirror them into a hidden input yourself.
TSX
import { useEffect, useRef } from "react";
import { useMediaDrop } from "react-mediadrop";
export function FormsExample() {
const { acceptedFiles, getRootProps, getInputProps } = useMediaDrop();
const hiddenInputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (!hiddenInputRef.current) return;
const dataTransfer = new DataTransfer();
for (const item of acceptedFiles) dataTransfer.items.add(item.file);
hiddenInputRef.current.files = dataTransfer.files;
}, [acceptedFiles]);
return (
<form className="space-y-3" onSubmit={(e) => e.preventDefault()}>
<div
{...getRootProps()}
className="cursor-pointer rounded-lg border-2 border-dashed border-zinc-300 px-6 py-10 text-center dark:border-zinc-700"
>
<input {...getInputProps()} />
<input
ref={hiddenInputRef}
type="file"
name="attachments"
multiple
className="hidden"
/>
<p>Drag files here, or click to browse</p>
</div>
<ul className="space-y-2">
{acceptedFiles.map((file) => (
<li
key={file.id}
className="rounded-md border border-zinc-200 px-3 py-2 text-sm dark:border-zinc-800"
>
{file.name} — {file.size.toLocaleString()} bytes
</li>
))}
</ul>
<button type="submit">Submit</button>
</form>
);
}Each MediaDropFile carries the original browser File on .file —
that’s what gets added to the hidden input’s DataTransfer. On submit,
the hidden input’s FileList goes out with the rest of the form fields.