Skip to main content
React Native Introduction
CHAPTER 11 Beginner

Working with Text, Images, and Buttons

Updated: May 16, 2026
6 min read

# CHAPTER 11

Working with Text, Images, and Buttons

1. Introduction

A beautifully structured flexbox layout is meaningless if there is no content inside it. In this chapter, we transition from structure to content. We will master Working with Text, Images, and Buttons. These three Core Components represent 95% of the visual elements in any modern application. You will learn how to properly format nested typography, safely load both local and network images, and build highly customizable, touch-responsive buttons using TouchableOpacity and Pressable.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Use the <Text> component and understand its nesting behaviors.
  • Load local assets and external URLs using the <Image> component.
  • Understand why the default <Button> component is rarely used by professionals.
  • Build custom, animated buttons using <TouchableOpacity>.
  • Add vector icons to your application using Expo Icons.

3. The <Text> Component

As discussed, you cannot render strings inside a <View>. They must be inside a <Text> component. Unlike <View>, <Text> components *do* support inheritance, but only for other <Text> components!
javascript
12345678910111213141516
import React from &#039;react&#039;;
import { Text, StyleSheet } from &#039;react-native&#039;;

export default function Typography() {
  return (
    // The child <Text> inherits the blue color, but overrides the boldness!
    <Text style={styles.baseText}>
      I am blue! <Text style={styles.boldText}>I am blue AND bold!</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  baseText: { color: &#039;blue&#039;, fontSize: 16 },
  boldText: { fontWeight: &#039;bold&#039; }
});

4. The <Image> Component

Mobile apps display two types of images: Local (stored inside the app file size) and Network (downloaded from the internet).

Local Images (Using require) Used for logos, icons, and static assets. They are bundled instantly.

javascript
1234
<Image 
  source={require(&#039;./assets/logo.png&#039;)} 
  style={{ width: 100, height: 100 }} 
/>

Network Images (Using uri) Used for user avatars or dynamic feed photos. Critical Rule: Network images will NOT render unless you provide a physical width and height in the style! React Native needs to know how much space to reserve while the image downloads.

javascript
1234
<Image 
  source={{ uri: &#039;https://example.com/avatar.jpg' }} 
  style={{ width: 200, height: 200, borderRadius: 100 }} 
/>

5. Why Not Use <Button>?

React Native provides a built-in <Button title="Click Me" onPress={doSomething} />. Do not use it for major UI design. The default <Button> is just a wrapper for the raw iOS and Android system buttons. It looks completely different on an iPhone versus an Android, and you cannot easily change its background color, padding, or text styling.

6. The Solution: <TouchableOpacity>

To create beautiful, cross-platform buttons, professionals use TouchableOpacity. It is basically a <View> that listens for clicks. When the user taps it, the entire component briefly fades out (dims the opacity), providing excellent visual feedback.
javascript
123456789101112131415161718192021222324252627282930
import { TouchableOpacity, Text, StyleSheet } from &#039;react-native&#039;;

export default function CustomButton() {
  return (
    // 1. The wrapper handles the click event and the dimming animation
    <TouchableOpacity 
      onPress={() => console.log(&#039;Pressed!&#039;)} 
      style={styles.button}
      activeOpacity={0.7} // How much it dims when pressed
    >
      {/* 2. The Text component holds the label */}
      <Text style={styles.buttonText}>Submit Data</Text>
    </TouchableOpacity>
  );
}

const styles = StyleSheet.create({
  button: {
    backgroundColor: &#039;#007BFF&#039;, // Nice blue
    paddingVertical: 12,
    paddingHorizontal: 30,
    borderRadius: 8,
  },
  buttonText: {
    color: &#039;white&#039;,
    fontSize: 16,
    fontWeight: &#039;600&#039;,
    textAlign: &#039;center&#039;, // Centers the text inside the button!
  }
});

*(Note: React Native also offers <Pressable>, which is a newer, more advanced version of TouchableOpacity that gives you granular control over hit-slop areas and custom press states).*

7. Adding Icons (Expo Vector Icons)

If you are using Expo, you have instant access to thousands of free SVG icons (Material Icons, FontAwesome, Ionicons) without installing any third-party libraries!
javascript
1234
import { Ionicons } from &#039;@expo/vector-icons&#039;;

// Inside your JSX return:
<Ionicons name="md-checkmark-circle" size={32} color="green" />

8. Mini Project: The Profile Header

Objective: Combine Text, Image, and TouchableOpacity into a cohesive unit.
javascript
123456789101112131415161718192021222324252627282930
import React from &#039;react&#039;;
import { View, Text, Image, TouchableOpacity, StyleSheet } from &#039;react-native&#039;;

export default function ProfileHeader() {
  return (
    <View style={styles.container}>
      <Image 
        source={{ uri: &#039;https://i.pravatar.cc/300' }} 
        style={styles.avatar} 
      />
      <View style={styles.infoBox}>
        <Text style={styles.name}>Jane Doe</Text>
        <Text style={styles.role}>Senior Developer</Text>
      </View>
      <TouchableOpacity style={styles.followBtn}>
        <Text style={styles.btnText}>Follow</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flexDirection: &#039;row&#039;, alignItems: &#039;center&#039;, padding: 20 },
  avatar: { width: 60, height: 60, borderRadius: 30 },
  infoBox: { flex: 1, marginLeft: 15 },
  name: { fontSize: 18, fontWeight: &#039;bold&#039; },
  role: { color: &#039;gray&#039; },
  followBtn: { backgroundColor: &#039;#FF3B30&#039;, padding: 10, borderRadius: 20 },
  btnText: { color: &#039;white&#039;, fontWeight: &#039;bold&#039; }
});

9. Common Mistakes

  • Invisible Network Images: You paste a valid URL into an <Image source={{uri: '...'}} /> tag, but the screen is totally blank. Why? Because you forgot to add style={{ width: 100, height: 100 }}. Network images have 0x0 dimensions by default.

10. Best Practices

  • Image Caching: Loading heavy 4K network images on every screen render will lag the app. For production apps, use libraries like expo-image or react-native-fast-image. They cache the image heavily to the phone's local storage so it loads instantly the next time the app is opened.

11. Practice Exercises

  1. 1. Write the code to display a local image named background.jpg located in your assets folder.
  1. 2. Why is <TouchableOpacity> preferred over the standard <Button> component when building a custom-designed signup screen?

12. MCQs with Answers

Question 1

A developer places an <Image> component in their app fetching a user's avatar from a remote URL. The URL is correct, but the image is completely invisible. What is the most likely cause?

Question 2

When styling nested typography, what unique behavior does the <Text> component exhibit that the <View> component does not?

13. Interview Questions

  • Q: Explain the syntax difference in the source prop when loading a local asset via the bundler versus loading a remote network asset. Why does this syntax difference exist?
  • Q: Contrast <TouchableOpacity> with <Pressable>. When would an architecture team strictly mandate the use of <Pressable> over the older Touchable components?
  • Q: How do you handle different image pixel densities (e.g., Retina displays, 2x, 3x) for local static assets in a React Native project to ensure they do not appear blurry on high-end devices?

14. FAQs

Q: My text is cutting off at the end of the screen instead of wrapping. How do I fix it? A: Ensure the parent <View> has flex: 1 or flexShrink: 1 applied. If you want the text to cleanly end with dots (e.g., "This is a long..."), use the numberOfLines={1} prop on the <Text> component!

15. Summary

In Chapter 11, we populated our structures with rich content. We mastered the <Text> component, utilizing nested inheritance for complex typography formatting. We successfully loaded both local and dynamic remote assets using the <Image> component, acknowledging the critical requirement of explicit dimensions for network fetches. Finally, we bypassed the rigid native <Button> limitations by constructing our own highly customizable, interactive elements using <TouchableOpacity>.

16. Next Chapter Recommendation

We can draw images and text, but what if we need to draw 500 of them? A standard View will just run off the bottom of the screen. Proceed to Chapter 12: Lists and ScrollView in React Native.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·