Skip to main content

Command Palette

Search for a command to run...

Navigations in React Native : Stack, Tabs, Params & Type Safety (For Beginners)

Published
3 min read
Navigations in React Native : Stack, Tabs, Params & Type Safety (For Beginners)
A

Full Stack Developer specializing in sleek, performant frontends and scalable backend systems I build production ready web applications with a focus on scalability, performance, and clean architecture. My expertise spans modern frontend development with React.js , Next.js and TypeScript, combined with robust backend systems.

On the backend, I specialize in Golang microservices using Fiber framework, implementing event-driven architectures with Kafka, caching strategies with Redis, and building efficient APIs with gRPC. I focus on creating scalable, maintainable systems that handle real-world complexity.

A clear, beginner-friendly guide using analogies, real-world examples, and working code to understand how to navigate React Native apps with Stack and Tab navigators using TypeScript.

What We’ll Learn

  1. Why we use Stack and Tab navigators together

  2. How navigation works like Google Maps

  3. What undefined in route types means

  4. Why and how to pass data between screens

  5. What CompositeScreenProps really does

  6. Full working code: App.tsx + TabNavigator + HomeScreen + Route Types


1. Why Use Stack + Tab Navigators?

Imagine your app is like a hotel:

  • Tabs = Floors (Home, Orders, Cart)

  • Stack Screens = Rooms on each floor (Details, Payment)

Users walk around using Tabs to switch floors, and use Stack navigation to enter specific rooms.

That’s why we use both together:

  • Tabs for main sections.

  • Stack for drill-down or detail screens.


2. How React Navigation Works (Google Maps Analogy)

Think of React Navigation like a Google Maps GPS system:

  • You enter a location like Details.

  • It expects a specific format, like { id: string }.

  • If you don't give the correct route data, it's like giving an incomplete address.

3. What Does undefined Mean in Route Types?

In this type:

export type RootTabParamList = {
  Home: undefined;
  Cart: undefined;
}

undefined means: “This route doesn’t need any parameters.”

But for routes with parameters, like Details:

export type RootStackParamList = {
  Details: { id: string };
}

This says: “To go to Details, you must pass an { id: string }.”


4. How to Pass Data Between Screens

Going from Home → Details:

navigation.push('Details', { id: 'abc123' });

In DetailsScreen.tsx, read it like:

const route = useRoute<NativeStackScreenProps<RootStackParamList, 'Details'>['route']>();
const { id } = route.params;

5. What Is CompositeScreenProps and Why We Need It

You're inside a tab (like Home) but also need access to the full-stack route (like pushing to Details). That’s when CompositeScreenProps is like a “combo-key” that gives you access to both doors.

type Props = CompositeScreenProps<
  BottomTabScreenProps<RootTabParamList, 'Home'>,
  NativeStackScreenProps<RootStackParamList>
>;
  • 👆 It merges types from Tab and Stack, so you can use navigation.push('Details') from inside a tab screen.

Full Code

src/types/navigation.ts

export type RootStackParamList = {
  Tab: undefined;
  Details: { id: string };
  Payment: undefined;
};

export type RootTabParamList = {
  Home: undefined;
  Cart: undefined;
  Favorite: undefined;
  Orders: undefined;
};

App.tsx

import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import TabNavigator from './src/navigator/TabNavigator';
import DetailsScreen from './src/screens/DetailsScreen';
import PaymentScreen from './src/screens/PaymentScreen';
import { RootStackParamList } from './src/types/navigation';

const Stack = createNativeStackNavigator<RootStackParamList>();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator screenOptions={{ headerShown: false }}>
        <Stack.Screen name="Tab" component={TabNavigator} />
        <Stack.Screen name="Details" component={DetailsScreen} />
        <Stack.Screen name="Payment" component={PaymentScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

TabNavigator.tsx

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import HomeScreen from '../screens/HomeScreen';
import CartScreen from '../screens/CartScreen';
import FavoritesScreen from '../screens/FavoritesScreen';
import OrderScreen from '../screens/OrderScreen';
import { RootTabParamList } from '../types/navigation';

const Tab = createBottomTabNavigator<RootTabParamList>();

export default function TabNavigator() {
  return (
    <Tab.Navigator screenOptions={{ headerShown: false }}>
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Cart" component={CartScreen} />
      <Tab.Screen name="Favorite" component={FavoritesScreen} />
      <Tab.Screen name="Orders" component={OrderScreen} />
    </Tab.Navigator>
  );
}

HomeScreen.tsx

import { View, Text, TouchableOpacity } from 'react-native';
import { CompositeScreenProps } from '@react-navigation/native';
import { BottomTabScreenProps } from '@react-navigation/bottom-tabs';
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import { RootTabParamList, RootStackParamList } from '../types/navigation';

type Props = CompositeScreenProps<
  BottomTabScreenProps<RootTabParamList, 'Home'>,
  NativeStackScreenProps<RootStackParamList>
>;

export default function HomeScreen({ navigation }: Props) {
  return (
    <View>
      <Text>Home</Text>
      <TouchableOpacity onPress={() => navigation.push('Details', { id: 'abc123' })}>
        <Text>Go to Details</Text>
      </TouchableOpacity>
    </View>
  );
}

Final Thoughts

You just learned how to build real-world navigation in React Native with:

Stack & Tab navigation
Type-safe route params
Accessing stack routes from tab screens
The mysterious undefined
CompositeScreenProps made easy

If this helped you, share it with another dev .

More from this blog

A

amanCodes

11 posts