Skip to content

1.4 Images

Learning Objectives

  • Render images from remote URLs and local assets using the Image component
  • Size images explicitly with required width/height properties on mobile
  • Control image scaling behavior using the resizeMode property
  • Understand why image sizing is fundamentally different on mobile vs web

Images in React Native are fundamentally different from images on the web. On web, you drop an <img> tag and the browser automatically figures out the size. On mobile, React Native requires you to be explicit about dimensions.

The Image component 1 renders images from two sources:

  • Remote URLs: Images hosted on a server (e.g., Unsplash, imgur, some API, etc.)
  • Local assets: Images bundled with your app during build time
// Remote image (requires uri key)
<Image
source={{ uri: 'https://example.com/photo.jpg' }}
style={{ width: 200, height: 150 }}
/>
// Local image (use require())
<Image
source={require('./logo.png')}
style={{ width: 200, height: 150 }}
/>

In general, remote images are more common since apps often fetch images from APIs or content delivery networks. Local images are useful for icons, logos, and other static assets.

On web, the browser can infer image dimensions from the file metadata. React Native running on mobile cannot do this upfront. It needs to know the space to reserve before the image loads. Without explicit width and height, React Native allocates zero space and your image disappears:

// ❌ Image won't show because no space was reserved
<Image source={{ uri: 'https://...' }} />
// ✅ Image renders because space was reserved
<Image
source={{ uri: 'https://...' }}
style={{ width: 200, height: 150 }}
/>

Have you ever seen images on the web “pop in” after loading and it shifts content around? That’s because the developer didn’t reserve space upfront. To mitigate this, React Native requires width and height styles on every image.

The simplest way to size an image is to specify exact numbers:

<Image source={{ uri: 'https://...' }} style={{ width: 200, height: 150 }} />

You can also use percentage widths in flexbox layouts:

<View style={{ width: 300 }}>
<Image
source={{ uri: 'https://...' }}
style={{ width: '100%', height: 200 }} // Fills parent width
resizeMode="cover"
/>
</View>
Use CaseExample
Avatarwidth: 80, height: 80 + borderRadius: 40
Card thumbnailwidth: '100%', height: 200 (fills card width)
Background heroflex: 1 on parent View (fills available space)

When an image’s aspect ratio doesn’t match its container, React Native needs to know how to scale it. The resizeMode property controls this behavior:

<Image
source={...}
resizeMode="cover" // or 'contain', 'center', 'stretch'
style={{ width: 200, height: 150 }}
/>
ModeBehaviorUse Case
coverScales to fill container, crops edges if neededHero images, photo grids, avatars
containScales to fit inside, adds empty space if neededProduct images, documents, art
centerShows original size centered in containerIcons, small graphics
stretchStretches to fill (may distort the image)Rare, usually avoid
  1. Open the Snack by clicking the icon in the toolbar.
  2. If not already logged in, create a free Expo account and sign in.
  3. Click the blue Save button to fork the Snack to your account.
  4. Make changes to the code and save your work.
  5. Submit on Moodle by copy-pasting the Snack URL into the submission box.

Build a reusable <Avatar /> component that:

  • Accepts a uri prop (image URL)
  • Renders a circular image (120x120, with rounded corners)
  • Has a 2px light gray border
  • Uses resizeMode="cover" so the image fills the circle
Hint

Think about the structure:

  1. Create a component function called Avatar that takes a uri prop
  2. Return a View with specific width/height (e.g., 120x120)
  3. Inside, render an Image with the uri as source
  4. Style the View with borderRadius: 60 to make it circular
  5. Add overflow: 'hidden' so the image respects the rounded corners
  6. Test by calling <Avatar uri="https://..." /> in App

Once it works, try using it multiple times in a row: <Avatar uri="..." /> <Avatar uri="..." /> <Avatar uri="..." />

  • Width and height are required on mobile. Unlike web, React Native doesn’t auto-size.
  • resizeMode controls aspect ratio: cover (crop), contain (fit), center (original), stretch (distort).
  • Remote images use { uri: 'https://...' }; local images use require('./file.png').
  • Show loading states with ActivityIndicator while images fetch.
  • Common pattern: borderRadius: size / 2 + overflow: 'hidden' creates perfect circles for avatars.
  • Circular images are everywhere in apps (avatars, profile pics, badges) Master this pattern!
  1. https://reactnative.dev/docs/image