How to build an accessible FileUploader in React

The drop zone is a real <button> so it is keyboard-operable (Enter/Space open the native file picker), the hidden file input is removed from the tab order and labelled via aria-describedby, and the file list uses aria-live="polite" so status changes are announced; each remove control carries an aria-label naming its file.

When to use a FileUploader

When not to use it

Keyboard interactions

Role button, verified at WCAG 2.2-AA.

Common mistakes

Avoid: Treating the component as uncontrolled and ignoring onFilesAdded

Prefer: Track accepted files in state and pass them back via the files prop

The file list is controlled — without wiring files/onFilesAdded/onRemove nothing renders in the list and status cannot update

Avoid: Relying only on accept/maxSize for security

Prefer: Re-validate type and size on the server after upload

Client-side accept/maxSize are UX filters, not enforcement; a determined user can bypass them

Example

<FileUploader onFilesAdded={console.log} />

See the full FileUploader reference →