Practice and reinforce the concepts from Lesson 11
Master mobile navigation patterns by:
Time Limit: 10 minutes
Install React Navigation:
npm install @react-navigation/native @react-navigation/native-stack
npx expo install react-native-screens react-native-safe-area-context
Basic Stack Navigator:
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
✅ Checkpoint: Navigation container loads without errors!
Time Limit: 5 minutes
Create a simple two-screen navigation:
function HomeScreen({ navigation }) {
return (
<View style={styles.container}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
✅ Checkpoint: Successfully navigate between screens!
Build a recipe app with these screens:
import React, { useState } from 'react';
import { View, Text, StyleSheet, FlatList, TouchableOpacity, Image } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
const recipes = [
{
id: '1',
title: 'Spaghetti Carbonara',
image: 'https://via.placeholder.com/150',
cookTime: '20 min',
difficulty: 'Easy'
},
// Add more recipes here
];
function RecipeListScreen({ navigation }) {
const renderRecipe = ({ item }) => (
<TouchableOpacity
style={styles.recipeCard}
onPress={() => navigation.navigate('RecipeDetails', { recipe: item })}
>
<Image source={{ uri: item.image }} style={styles.recipeImage} />
<View style={styles.recipeInfo}>
<Text style={styles.recipeTitle}>{item.title}</Text>
<Text style={styles.recipeDetails}>{item.cookTime} • {item.difficulty}</Text>
</View>
</TouchableOpacity>
);
return (
<View style={styles.container}>
<FlatList
data={recipes}
renderItem={renderRecipe}
keyExtractor={item => item.id}
/>
</View>
);
}
function RecipeDetailsScreen({ route, navigation }) {
const { recipe } = route.params;
return (
<View style={styles.container}>
<Image source={{ uri: recipe.image }} style={styles.heroImage} />
<Text style={styles.title}>{recipe.title}</Text>
<Text style={styles.cookTime}>{recipe.cookTime} • {recipe.difficulty}</Text>
{/* Add ingredients and instructions here */}
</View>
);
}
Your Mission:
Add bottom tab navigation:
npm install @react-navigation/bottom-tabs
npx expo install react-native-vector-icons
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Ionicons } from '@expo/vector-icons';
const Tab = createBottomTabNavigator();
function TabNavigator() {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Recipes') {
iconName = focused ? 'restaurant' : 'restaurant-outline';
} else if (route.name === 'Favorites') {
iconName = focused ? 'heart' : 'heart-outline';
} else if (route.name === 'Profile') {
iconName = focused ? 'person' : 'person-outline';
}
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: '#e74c3c',
tabBarInactiveTintColor: 'gray',
})}
>
<Tab.Screen name="Recipes" component={RecipeStackNavigator} />
<Tab.Screen name="Favorites" component={FavoritesScreen} />
<Tab.Screen name="Profile" component={ProfileScreen} />
</Tab.Navigator>
);
}
Implement these navigation patterns:
// Modal navigation
function CreateRecipeModal({ navigation }) {
return (
<View style={styles.modalContainer}>
<View style={styles.modalHeader}>
<TouchableOpacity onPress={() => navigation.goBack()}>
<Text style={styles.cancelButton}>Cancel</Text>
</TouchableOpacity>
<Text style={styles.modalTitle}>New Recipe</Text>
<TouchableOpacity onPress={() => navigation.goBack()}>
<Text style={styles.saveButton}>Save</Text>
</TouchableOpacity>
</View>
{/* Add recipe creation form here */}
</View>
);
}
// Custom header with actions
React.useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<TouchableOpacity onPress={toggleFavorite}>
<Ionicons
name={isFavorite ? 'heart' : 'heart-outline'}
size={24}
color="#e74c3c"
/>
</TouchableOpacity>
),
});
}, [navigation, isFavorite]);
Completed Successfully If:
Time Investment: 60 minutes total Difficulty Level: Intermediate Prerequisites: Basic React Native knowledge, component state management Tools Needed: Expo development environment, React Navigation libraries