Topic 10 of 15 · React Native

Topic 10 : Libraries (Image picker, react elements)

Lesson TL;DRTopic 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 — wr...
6 min read·intermediate·react-native · libraries · fast-image · document-picker

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-image to display images with priority control and resize modes
  • Install and use react-native-document-picker to open a native file picker and read file metadata
  • Install and use react-native-elements (with react-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.priorityFastImage.priority.low | .normal | .high controls download order when multiple images load simultaneously
  • resizeModeFastImage.resizeMode.cover | .contain | .stretch | .center mirrors CSS object-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:

FieldDescription
nameOriginal filename
sizeFile size in bytes
uriLocal URI to the temporary copy
typeMIME 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 to react-native-vector-icons/MaterialIcons by default; pass type="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.

  1. Change the type array to [DocumentPicker.types.images].
  2. Switch DocumentPicker.pick to DocumentPicker.pickMultiple so the user can select more than one image.
  3. Store the result array in state and render {files.length} image(s) selected below 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-image wraps native image loaders for caching and priority control; use FastImage.priority and FastImage.resizeMode instead of the bare <Image> props.
  • react-native-document-picker opens the OS file picker; always check DocumentPicker.isCancel(err) in the catch block to avoid treating a user dismissal as an error.
  • react-native-elements provides consistent cross-platform UI components (Card, Button, Icon) and requires react-native-vector-icons as a peer dependency.
  • Compose independent feature components into App.js using ScrollView with flexGrow: 1 on contentContainerStyle so the layout centers on short screens and scrolls on tall ones.

📚 Further Reading

Like this topic? It’s one of 15 in React Native.

Block your seat for ₹2,500 and join the next cohort.