whenever life put's you in a tough situtation, never say why me! but, try me!

Chapter 9: Expo Router Stack Navigation


1. What is Stack Navigation in Expo Router?

Stack Navigation is a navigation pattern that organizes the navigation history in a stack, allowing users to push and pop screens off the stack. It mimics the navigation flow of most mobile apps where users can move forward to a new screen and back to the previous one.

Key Points:

  • Stack-Based Navigation: Each new screen is pushed onto a stack.
  • Back Button: Users can navigate back to the previous screen.
  • History Management: Stack navigation manages the history of screens for easy back-and-forth navigation.

Example Scenario: Navigating from a Home screen to a Details screen and then back to Home.

2. Setting Up Expo Stack Navigator

To use Stack navigation in your Expo project, you’ll use the Stack component from expo-router/stack. Below are the steps to set it up:

Step 1: Install Necessary Dependencies

  • Ensure that your Expo project is set up with expo-router. The Expo Router is included by default in newer Expo projects.

Step 2: Create a File Structure for Navigation

  • Use file-based routing with Expo. Each screen is a .js or .tsx file within the app/ directory.

Example File Structure:

app/
├── _layout.js
├── index.js
├── details.js

Step 3: Define the Stack Navigator

  • Use the Stack component from expo-router/stack in your _layout.js file to set up the stack navigation for your app.
// app/_layout.js
import { Stack } from "expo-router/stack";

export default function Layout() {
  return (
    <Stack>
      <Stack.Screen name="index" options={{ title: "Home" }} />
      <Stack.Screen name="details" options={{ title: "Details" }} />
    </Stack>
  );
}

Step 4: Create Screens

  • Define the Home and Details screens in their respective files.
// app/index.js
import { Link } from "expo-router";
import { View, Text, Button, StyleSheet } from "react-native";

export default function HomeScreen() {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Home Screen</Text>
      <Link href="/details">
        <Button title="Go to Details" />
      </Link>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  title: {
    fontSize: 24,
    marginBottom: 20,
  },
});
// app/details.js
import { View, Text, Button, StyleSheet } from "react-native";
import { useRouter } from "expo-router";

export default function DetailsScreen() {
  const router = useRouter();

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Details Screen</Text>
      <Button title="Go Back" onPress={() => router.back()} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  title: {
    fontSize: 24,
    marginBottom: 20,
  },
});

3. Creating and Navigating Between Screens

Navigating Between Screens:

  • Navigation in Expo Router is straightforward. You can use the Link component or programmatically navigate using useRouter.

Example:

  • From the Home screen to the Details screen using a button.
// app/index.js (continued)
<Link href="/details">
  <Button title="Go to Details" />
</Link>
  • Programmatic navigation using useRouter.
// app/index.js (alternative)
import { useRouter } from "expo-router";

export default function HomeScreen() {
  const router = useRouter();

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Home Screen</Text>
      <Button title="Go to Details" onPress={() => router.push("/details")} />
    </View>
  );
}

4. Handling Navigation State

Handling navigation state in a stack navigator is crucial for managing the app's flow. Expo Router's Stack component provides access to navigation state through various hooks and props.

Common Tasks:

  • Detecting Screen Focus: Using useFocusEffect to trigger actions when a screen gains focus.
  • Accessing Navigation Parameters: Using useSearchParams to retrieve parameters passed between screens.

Example: Detecting Screen Focus

import { useFocusEffect } from "expo-router";
import { useCallback } from "react";
import { View, Text } from "react-native";

export default function DetailsScreen() {
  useFocusEffect(
    useCallback(() => {
      console.log("Screen is focused");
      return () => console.log("Screen is unfocused");
    }, [])
  );

  return (
    <View>
      <Text>Details Screen</Text>
    </View>
  );
}

Example: Accessing Navigation Parameters

import { useSearchParams } from "expo-router";

export default function DetailsScreen() {
  const { itemId } = useSearchParams();

  return (
    <View>
      <Text>Details Screen for Item ID: {itemId}</Text>
    </View>
  );
}

5. Customizing Stack Navigation with All Different ScreenOptions

You can customize the look and feel of your stack navigator using the ScreenOptions prop. This allows you to set properties like header styles, gestures, animations, etc.

Common ScreenOptions:

  • headerStyle: Customizes the header's background color.
  • headerTintColor: Changes the color of the header text and icons.
  • headerTitleStyle: Adjusts the font size, weight, and alignment of the header title.
  • gestureEnabled: Enables or disables gestures like swiping back.

Example: Customizing Screen Options

// app/_layout.js
import { Stack } from "expo-router/stack";

export default function Layout() {
  return (
    <Stack>
      <Stack.Screen
        name="index"
        options={{
          title: "Home",
          headerStyle: { backgroundColor: "#f4511e" },
          headerTintColor: "#fff",
          headerTitleStyle: { fontWeight: "bold" },
        }}
      />
      <Stack.Screen
        name="details"
        options={{
          title: "Details",
          gestureEnabled: true,
          headerBackTitle: "Back to Home",
        }}
      />
    </Stack>
  );
}

Example: Animations and Gestures

// app/_layout.js
<Stack.Screen
  name="details"
  options={{
    animationEnabled: true,
    gestureEnabled: true,
    headerStyle: {
      backgroundColor: "blue",
    },
    headerTintColor: "white",
  }}
/>

This chapter provides a comprehensive guide to setting up and using Stack Navigation with Expo Router. By following these examples and understanding the underlying concepts, you'll be able to implement efficient and user-friendly navigation in your React Native Expo applications.