Topic 10: Libraries (Image Picker, React Elements)
📖 6 min read · 🎯 intermediate · 🧭 Prerequisites: http, navigation
Why this matters
Up until now, you've been building everything from scratch — writing your own button styles, loading images with the basic Image component, and wondering why your app feels a little rough around the edges. Every real React Native project reaches a point where you stop reinventing the wheel. That's where libraries come in. In this lesson, we'll plug in three powerful ones: react-native-fast-image for smooth, cached image loading, react-native-document-picker for letting users select files, and react-native-elements for ready-made, polished UI components. Your app is about to level up fast.
What You'll Learn
- Install and use
react-native-fast-imageto display images with priority control and resize modes - Install and use
react-native-document-pickerto open a native file picker and read file metadata - Install and use
react-native-elements(withreact-native-vector-icons) to build cards, buttons, and icons - Compose all three components into a single scrollable
App.js
The Analogy
Think of your app as a ranger outpost. The outpost has three supply departments: the photo lab (react-native-fast-image) that develops and caches images so scouts don't have to fetch the same photo twice; the document archive (react-native-document-picker) that lets rangers grab any file from their kit and hand it to HQ; and the quartermaster (react-native-elements) that issues standardized, well-designed gear — buttons, cards, icons — so every ranger looks sharp without tailoring their own uniform from scratch. You don't reinvent any of these departments; you just requisition from them.
Chapter 1: Handling Images with react-native-fast-image
The built-in <Image> component works, but it doesn't cache aggressively or expose request priority. react-native-fast-image wraps a native image loader (Glide on Android, SDWebImage on iOS) to give you caching, priority queuing, and reliable resize modes.
Step 1: Install the library
npm install react-native-fast-image
Step 2: Link the library (older React Native versions only)
Modern React Native (0.60+) auto-links native modules. If you are on an older version you must link manually:
react-native link react-native-fast-image
Step 3: Create ImageComponent.js
import React from 'react';
import { StyleSheet, View } from 'react-native';
import FastImage from 'react-native-fast-image';
const ImageComponent = () => {
return (
<View style={styles.container}>
<FastImage
style={styles.image}
source={{
uri: 'https://your-image-url.com/image.jpg',
priority: FastImage.priority.normal,
}}
resizeMode={FastImage.resizeMode.cover}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
image: {
width: 200,
height: 200,
},
});
export default ImageComponent;
Key FastImage props to know:
source.priority—FastImage.priority.low | .normal | .highcontrols download order when multiple images load simultaneouslyresizeMode—FastImage.resizeMode.cover | .contain | .stretch | .centermirrors CSSobject-fit
Chapter 2: Picking Files with react-native-document-picker
react-native-document-picker opens the native OS file picker (Files app on iOS, Storage Access Framework on Android) and returns metadata about whatever the user selects.
Step 1: Install the library
npm install react-native-document-picker
Step 2: Link the library (older React Native versions only)
react-native link react-native-document-picker
Step 3: Create FilePickerComponent.js
import React, { useState } from 'react';
import { View, Button, Text, StyleSheet } from 'react-native';
import DocumentPicker from 'react-native-document-picker';
const FilePickerComponent = () => {
const [file, setFile] = useState(null);
const pickFile = async () => {
try {
const result = await DocumentPicker.pick({
type: [DocumentPicker.types.allFiles],
});
setFile(result);
} catch (err) {
if (DocumentPicker.isCancel(err)) {
console.log('User cancelled the picker');
} else {
console.log('Unknown error:', err);
}
}
};
return (
<View style={styles.container}>
<Button title="Pick a File" onPress={pickFile} />
{file && (
<Text style={styles.fileInfo}>
{file.name} ({file.size} bytes)
</Text>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
fileInfo: {
marginTop: 20,
},
});
export default FilePickerComponent;
What the result object contains:
| Field | Description |
|---|---|
name | Original filename |
size | File size in bytes |
uri | Local URI to the temporary copy |
type | MIME type string |
DocumentPicker.isCancel(err) lets you distinguish a user dismissal from a real error so you don't show a spurious error toast.
DocumentPicker.types.allFiles accepts every file type. You can narrow it — e.g., DocumentPicker.types.images or DocumentPicker.types.pdf.
Chapter 3: Enhancing UI with react-native-elements
react-native-elements is a cross-platform UI toolkit that ships Button, Card, Icon, Text, Input, Avatar, and more — all consistent between iOS and Android. Icons come from react-native-vector-icons, which is a peer dependency.
Step 1: Install both packages
npm install react-native-elements
npm install react-native-vector-icons
Step 2: Create UIComponent.js
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { Button, Card, Icon, Text } from 'react-native-elements';
const UIComponent = () => {
return (
<View style={styles.container}>
<Card>
<Card.Title>React Native Elements</Card.Title>
<Card.Divider />
<Text style={styles.text}>
This is a card with some text and a button.
</Text>
<Button
icon={<Icon name="code" color="#ffffff" />}
buttonStyle={styles.button}
title="BUTTON"
/>
</Card>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
marginBottom: 10,
},
button: {
backgroundColor: '#03A9F4',
},
});
export default UIComponent;
Notable react-native-elements patterns used here:
<Card>wraps<Card.Title>and<Card.Divider>as sub-components — no separate imports needed<Button icon={...}>accepts any React element as the leading icon<Icon name="code">resolves toreact-native-vector-icons/MaterialIconsby default; passtype="font-awesome"etc. to switch icon sets
Chapter 4: Combining All Components in App.js
With all three components built, the class wires them into a single scrollable screen so each piece can be demonstrated together.
import React from 'react';
import { StyleSheet, ScrollView, View } from 'react-native';
import ImageComponent from './ImageComponent';
import FilePickerComponent from './FilePickerComponent';
import UIComponent from './UIComponent';
export default function App() {
return (
<ScrollView contentContainerStyle={styles.container}>
<ImageComponent />
<FilePickerComponent />
<UIComponent />
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
flexGrow: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 16,
},
});
flexGrow: 1 on contentContainerStyle keeps the content centered when it's shorter than the screen, while still allowing scroll when it overflows. Use ScrollView rather than View here because FastImage, DocumentPicker, and Card can combine to exceed a single viewport height on smaller devices.
graph TD
A[App.js ScrollView] --> B[ImageComponent]
A --> C[FilePickerComponent]
A --> D[UIComponent]
B --> E[react-native-fast-image]
C --> F[react-native-document-picker]
D --> G[react-native-elements]
D --> H[react-native-vector-icons]
🧪 Try It Yourself
Task: Add a second file type filter to FilePickerComponent so it only accepts images (not all files), then display a preview count of how many files were picked.
- Change the
typearray to[DocumentPicker.types.images]. - Switch
DocumentPicker.picktoDocumentPicker.pickMultipleso the user can select more than one image. - Store the result array in state and render
{files.length} image(s) selectedbelow the button.
Starter snippet:
const pickFile = async () => {
try {
const results = await DocumentPicker.pickMultiple({
type: [DocumentPicker.types.images],
});
setFile(results); // results is an array
} catch (err) {
if (DocumentPicker.isCancel(err)) {
console.log('User cancelled the picker');
} else {
console.log('Unknown error:', err);
}
}
};
Success criterion: After selecting two images, you should see 2 image(s) selected rendered beneath the button without any errors in the Metro console.
🔍 Checkpoint Quiz
Q1. Why does react-native-fast-image outperform the built-in <Image> component for most production use cases?
A) It supports more file formats
B) It uses native caching libraries (Glide/SDWebImage) and exposes priority control
C) It automatically compresses images before display
D) It is built into React Native core
Q2. Given this snippet, what happens when the user taps "Pick a File" and then presses the system back button without selecting anything?
const pickFile = async () => {
try {
const result = await DocumentPicker.pick({
type: [DocumentPicker.types.allFiles],
});
setFile(result);
} catch (err) {
if (DocumentPicker.isCancel(err)) {
console.log('User cancelled the picker');
} else {
console.log('Unknown error:', err);
}
}
};
A) The app crashes with an unhandled promise rejection
B) setFile is called with null
C) "User cancelled the picker" is logged and the file state is unchanged
D) The picker reopens automatically
Q3. What bug exists in this component?
import { Button, Card, Icon } from 'react-native-elements';
const Broken = () => (
<Card>
<Card.Title>Hello</Card.Title>
<Button
icon={<Icon name="star" />}
title="Go"
/>
</Card>
);
A) Card.Title is not a valid sub-component
B) react-native-vector-icons is missing — Icon will fail to render without it installed as a peer dependency
C) Button cannot accept an icon prop
D) Card must be imported from react-native not react-native-elements
Q4. You are building a document-scanning feature that lets users pick a PDF, upload it to a server, and show a progress indicator. Which DocumentPicker.types value would you pass, and what field in the picker result gives you the local file path to read before uploading?
A1. B — react-native-fast-image delegates caching to Glide (Android) and SDWebImage (iOS), which are mature, battle-tested native libraries. It also lets you set download priority so critical above-the-fold images load before decorative ones.
A2. C — Dismissing the picker without a selection throws a cancel error. DocumentPicker.isCancel(err) returns true for this case, so the catch block logs "User cancelled the picker" and setFile is never called, leaving state unchanged.
A3. B — react-native-elements depends on react-native-vector-icons as a peer dependency for the Icon component. If it isn't installed (and linked/auto-linked), the Icon will either crash or render nothing. The component code itself is otherwise correct.
A4. Use DocumentPicker.types.pdf to restrict selection to PDF files. The uri field in the result object contains the local file path (a temporary copy on the device) that you pass to your upload function.
🪞 Recap
react-native-fast-imagewraps native image loaders for caching and priority control; useFastImage.priorityandFastImage.resizeModeinstead of the bare<Image>props.react-native-document-pickeropens the OS file picker; always checkDocumentPicker.isCancel(err)in the catch block to avoid treating a user dismissal as an error.react-native-elementsprovides consistent cross-platform UI components (Card,Button,Icon) and requiresreact-native-vector-iconsas a peer dependency.- Compose independent feature components into
App.jsusingScrollViewwithflexGrow: 1oncontentContainerStyleso the layout centers on short screens and scrolls on tall ones.
📚 Further Reading
- react-native-fast-image GitHub — full API reference including preloading and cache control
- react-native-document-picker GitHub — all
typesconstants and multi-file selection docs - React Native Elements docs — component gallery with live prop tables
- react-native-vector-icons directory — browse all icon sets by name before wiring them up
- ⬅️ Previous: Navigation
- ➡️ Next: Redux