Skip to main content
React Native Introduction
CHAPTER 15 Beginner

React Native Screens and Routing

Updated: May 16, 2026
7 min read

# CHAPTER 15

React Native Screens and Routing

1. Introduction

In the previous chapter, we built the navigation highway, but we didn't drive on it. We established the NavigationContainer and the Stack, but the user is currently stuck on the Home screen. How do we program a button to push the Details screen? How do we pass the ID of the clicked product from Home to Details? In this chapter, we will master React Native Screens and Routing. We will utilize the injected navigation prop to trigger screen transitions, securely pass dynamic parameters between routes, and architect the highly popular Bottom Tab Navigator.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Use the navigation.navigate() function to push new screens.
  • Use navigation.goBack() to programmatically pop screens.
  • Pass complex objects and parameters between screens.
  • Extract passed data using the route.params object.
  • Install and configure a Bottom Tab Navigator.

3. Moving Between Screens (navigation.navigate)

When you register a screen in the <Stack.Navigator> (e.g., <Stack.Screen name="Home" component={HomeScreen} />), React Navigation performs a magic trick. It automatically injects a special prop called navigation directly into that Component!

We can destructure this prop and use its navigate('ScreenName') method!

javascript
1234567891011121314
// 1. Destructure the magical 'navigation' prop!
function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: &#039;center&#039;, justifyContent: &#039;center&#039; }}>
      <Text>Home Screen</Text>
      
      <Button
        title="Go to Details"
        // 2. Call navigate() using the EXACT string name registered in App.js!
        onPress={() => navigation.navigate(&#039;Details&#039;)} 
      />
    </View>
  );
}

*Note: If you are deep inside a custom nested component (like a custom Button class) that isn't directly registered in App.js, you won't have the prop. You must import the useNavigation() hook to access the routing functions!*

4. Passing Parameters (Data Transfer)

Navigating is easy, but what if HomeScreen is a list of 100 products? When the user taps product #42, the DetailsScreen needs to know *which* product to fetch from the database! We pass parameters by adding a second argument to .navigate(), formatted as a JSON object.

Screen 1 (Sender):

javascript
12345678910
<Button
  title="View Product 42"
  onPress={() => {
    // Navigate to Details, and send a data payload!
    navigation.navigate(&#039;Details&#039;, {
      itemId: 42,
      productName: &#039;Wireless Headphones&#039;,
    });
  }}
/>

5. Reading Parameters (route.params)

Just as React Navigation injects the navigation prop to handle movement, it also injects a route prop to handle data!

Screen 2 (Receiver):

javascript
1234567891011121314
// Destructure the magical 'route' prop!
function DetailsScreen({ route }) {
  
  // Extract the specific data we sent from the previous screen!
  const { itemId, productName } = route.params;

  return (
    <View style={{ flex: 1, alignItems: &#039;center&#039; }}>
      <Text>Now viewing details for:</Text>
      <Text style={{ fontSize: 24, fontWeight: &#039;bold&#039; }}>{productName}</Text>
      <Text>Database ID: {itemId}</Text>
    </View>
  );
}

6. The Bottom Tab Navigator

A Stack Navigator is great for drilling deep into details. But the main interface of most modern apps (Instagram, Spotify) is a Bottom Tab bar.
  1. 1. Install it: npm install @react-navigation/bottom-tabs
  1. 2. Import it into App.js: import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

Let's replace our Stack with a beautiful Tab system!

javascript
12345678910111213141516171819202122232425262728293031323334353637
import React from &#039;react&#039;;
import { NavigationContainer } from &#039;@react-navigation/native&#039;;
import { createBottomTabNavigator } from &#039;@react-navigation/bottom-tabs&#039;;
import { Ionicons } from &#039;@expo/vector-icons&#039;; // Assuming Expo

import FeedScreen from &#039;./screens/FeedScreen&#039;;
import ProfileScreen from &#039;./screens/ProfileScreen&#039;;

const Tab = createBottomTabNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator
        screenOptions={({ route }) => ({
          // Set active/inactive colors
          tabBarActiveTintColor: &#039;tomato&#039;,
          tabBarInactiveTintColor: &#039;gray&#039;,
          
          // Dynamically assign icons based on the route name!
          tabBarIcon: ({ focused, color, size }) => {
            let iconName;
            if (route.name === &#039;Feed&#039;) {
              iconName = focused ? &#039;home&#039; : &#039;home-outline&#039;;
            } else if (route.name === &#039;Profile&#039;) {
              iconName = focused ? &#039;person&#039; : &#039;person-outline&#039;;
            }
            return <Ionicons name={iconName} size={size} color={color} />;
          },
        })}
      >
        <Tab.Screen name="Feed" component={FeedScreen} />
        <Tab.Screen name="Profile" component={ProfileScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

7. Combining Navigators (Nesting)

Real apps combine them! The root App.js holds a Stack.Navigator. The very first screen in that stack (Home) actually points to a Tab.Navigator Component instead of a standard UI screen. When a user clicks an item inside the Tab feed, it pushes a Detail screen *over* the entire Tab bar using the parent Stack!

8. Visual Learning: The Navigation Flow

txt
123456789
[ Home Screen ]
      | (User taps "View Details")
      | navigation.navigate(&#039;Details', { id: 7 })
      v
[ Details Screen ]
      | (Reads route.params.id -> outputs 7)
      | (User taps top-left physical Back Arrow)
      v
[ Home Screen ] (Restored instantly from Stack)

9. Common Mistakes

  • Passing Massive Objects in Params: It is tempting to pass a 5MB JSON object of a User Profile via route.params. This is an architectural anti-pattern. If the app is minimized, Android will struggle to serialize massive params and may crash. You should ONLY pass minimal identifiers (like userId: 42). The Details screen should then take that ID and fetch the full 5MB object from Global State (Redux) or a fast SQLite database!

10. Best Practices

  • TypeScript Navigation Types: If you are using TypeScript, defining strict types for your Route Params prevents you from accidentally trying to read route.params.userName when the previous screen actually sent route.params.name, eliminating runtime typo crashes.

11. Practice Exercises

  1. 1. What specific method on the navigation object is used to trigger a transition to a screen registered under the name "Settings"?
  1. 2. Write the object syntax required to pass a variable score = 100 alongside a navigation transition to the "GameOver" screen.

12. MCQs with Answers

Question 1

A component deeply nested inside your application hierarchy (e.g., a tiny LikeButton inside a PostCard inside a FeedList) needs to navigate to a new screen. However, because it is not directly registered in App.js, it does not automatically receive the navigation prop. How do you solve this?

Question 2

When data is passed from Screen A to Screen B via navigation.navigate(), which specific prop injected by React Navigation into Screen B must be destructured to extract that data payload?

13. Interview Questions

  • Q: Explain the paradigm of "Nesting Navigators" in React Native. Describe a common architecture where a Stack Navigator and a Bottom Tab Navigator are combined.
  • Q: Why is passing excessively large JSON objects via route.params considered a severe architectural anti-pattern? What is the correct pattern for data retrieval on a pushed Detail screen?
  • Q: Describe how you would utilize the navigation.goBack() method versus navigation.popToTop(). Provide a specific UX scenario for each.

14. FAQs

Q: Can I open a specific screen in my app from an email link? A: Yes! This is called Deep Linking. You configure React Navigation with a specific linking prefix (like myapp://). If the user clicks myapp://details/42 in an email, the app launches, parses the URL, automatically navigates to the Details screen, and injects 42 into the route.params!

15. Summary

In Chapter 15, we brought fluidity to our application architecture. We mastered the injection of the navigation prop, executing .navigate() to dynamically traverse our Stack routes. We securely established data pipelines between independent screens by passing payloads and extracting them meticulously via route.params. Finally, we leveled up our UX by installing and configuring a professional, icon-driven Bottom Tab Navigator, preparing us to build complex, deeply nested app structures.

16. Next Chapter Recommendation

Passing an ID between two screens is easy. But what if the User Profile on Tab 3 needs to know that an item was added to the Shopping Cart on Tab 1? Passing params through 10 screens is impossible. We need a Global Cloud. Proceed to Chapter 16: State Management with Context API.

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: ·