1. 21:34 06/10/2026
When building a file upload feature in a React Native app, developers often focus on the backend handling and progress indicators. Equally important is providing immediate feedback to the user through real‑time validation and preview. This article walks through a practical approach to add these capabilities while keeping the code clean and maintainable.
**Why Real‑Time Validation and Preview Matter**
* **Reduced friction:** Users can see instantly whether a selected file meets the required criteria.
* **Lower error rates:** Early validation prevents unnecessary API calls and server‑side rejections.
* **Enhanced confidence:** A quick preview lets users confirm the correct content before uploading.
**Core Validation Logic**
1. **Define allowed types and sizes** – Store these in a simple config object so they can be reused across the component.
2. **Create a validation function** – This function receives the file object (or FileList) and returns an error message or null if everything is okay.
3. **Integrate with the picker** – Most React Native image/video pickers return a promise; wrap the result in a state update and run validation as soon as the file is selected.
```javascript
// Example validation utility
const validateFile = (file) => {
const maxSize = 5 * 1024 * 1024; // 5 MB
const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];
if (!allowedTypes.includes(file.type)) {
return 'File type not supported';
}
if (file.size > maxSize) {
return 'File exceeds 5 MB limit';
}
return null;
};
```
**Providing Instant Previews**
* **Images:** Use `react‑native‑image‑picker` together with an `<Image>` component. Convert the local URI to a base64 string only when needed for preview.
* **PDFs and other documents:** Show a generic document icon and, if you want a quick glance, embed the PDF in an `<WebView>` for a single‑page preview.
* **State management:** Keep `previewUri`, `previewType`, and `validationError` in a single state object. This makes it easy to conditionally render the preview or error message.
**Putting It All Together**
```javascript
const [uploadState, setUploadState] = useState({
file: null,
previewUri: null,
previewType: null,
error: null,
progress: 0,
});
const pickAndValidate = async () => {
const result = await ImagePicker.launchImageLibrary({
mediaType: 'mixed',
quality: 1,
});
if (!result.canceled && result.assets.length > 0) {
const selected = result.assets[0];
const err = validateFile(selected);
setUploadState(prev => ({
...prev,
file: selected,
error: err,
previewUri: err ? null : selected.uri,
previewType: err ? null : selected.type,
}));
}
};
```
**Best Practices**
* **Chunk large files:** If you anticipate uploads larger than a few megabytes, split the file into slices before sending.
* **Show a progress bar:** Update the `progress` field while the network request is in flight.
* **Clear errors gracefully:** Allow the user to correct the issue and re‑trigger validation.
* **Accessibility:** Pair error messages with `aria‑live` regions so screen readers announce changes.
By following these patterns, you can deliver a smooth, confident user experience that feels native to both iOS and Android platforms. The combination of immediate validation and preview reduces friction, cuts down on failed uploads, and ultimately makes your React Native app more polished.