🚀 React Native Advanced Navigation
Your App is Like a House with Many Rooms
Imagine your app is a big house. Each screen is a room. Basic navigation is like having plain doors between rooms. But Advanced Navigation? That’s like having:
- Magical doors that change color based on the time of day (Theming)
- Secret tunnels that take you directly to any room from outside (Deep Links)
- A smart guard at the entrance checking if you’re allowed in (Auth Flow)
- Labels on everything so you never get confused (TypeScript)
Let’s explore each magical door! 🚪✨
🎨 Navigation Theming
What is It?
Think of your favorite app at night. Does it turn dark? That’s theming! Navigation Theming lets you dress up your navigation bars, headers, and backgrounds to match your app’s mood.
The Simple Story
Imagine you have a coloring book. Every page has the same picture, but YOU decide what colors to use. Navigation Theming is exactly that—you decide how your app’s navigation looks and feels.
How Does It Work?
React Navigation has a built-in theme system. You give it a color recipe, and it paints everything for you!
// Your color recipe (theme)
const MyTheme = {
dark: false,
colors: {
primary: '#6200ee',
background: '#ffffff',
card: '#f5f5f5',
text: '#000000',
border: '#cccccc',
notification: '#ff0000',
},
};
Using Your Theme
import { NavigationContainer } from
'@react-navigation/native';
function App() {
return (
<NavigationContainer theme={MyTheme}>
{/* Your screens go here */}
</NavigationContainer>
);
}
Dark Mode Made Easy
Want dark mode? Just create TWO themes and switch!
const LightTheme = {
dark: false,
colors: {
primary: '#6200ee',
background: '#ffffff',
card: '#ffffff',
text: '#000000',
border: '#e0e0e0',
notification: '#ff0000',
},
};
const DarkTheme = {
dark: true,
colors: {
primary: '#bb86fc',
background: '#121212',
card: '#1e1e1e',
text: '#ffffff',
border: '#333333',
notification: '#ff0000',
},
};
Switching Themes
function App() {
const [isDark, setIsDark] = useState(false);
return (
<NavigationContainer
theme={isDark ? DarkTheme : LightTheme}
>
{/* Screens */}
</NavigationContainer>
);
}
Using Theme Colors in Your Screens
import { useTheme } from '@react-navigation/native';
function MyScreen() {
const { colors } = useTheme();
return (
<View style={{
backgroundColor: colors.background
}}>
<Text style={{ color: colors.text }}>
Hello!
</Text>
</View>
);
}
graph TD A["🎨 Theme Object"] --> B["NavigationContainer"] B --> C["Header Colors"] B --> D["Tab Bar Colors"] B --> E["Screen Backgrounds"] C --> F["Your App Looks Beautiful!"] D --> F E --> F
🔗 Deep Link Navigation
What is It?
Remember when you click a link and it opens exactly the right page in an app? Like magic! That’s Deep Linking.
The Simple Story
Imagine you’re in a huge mall. Deep links are like giving someone your exact location:
- ❌ “I’m somewhere in the mall” (Not helpful!)
- ✅ “I’m at Floor 3, Shop 42, near the blue shelf” (Perfect!)
Deep links are exact addresses to screens in your app.
How URLs Become Screens
myapp://profile/john
↓
Opens Profile screen for user "john"
Setting Up Deep Links
Step 1: Configure Your Link Structure
const linking = {
prefixes: ['myapp://', 'https://myapp.com'],
config: {
screens: {
Home: 'home',
Profile: 'profile/:userId',
Settings: 'settings',
Product: 'product/:productId',
},
},
};
Step 2: Pass to NavigationContainer
function App() {
return (
<NavigationContainer linking={linking}>
<Stack.Navigator>
<Stack.Screen name="Home" />
<Stack.Screen name="Profile" />
<Stack.Screen name="Settings" />
<Stack.Screen name="Product" />
</Stack.Navigator>
</NavigationContainer>
);
}
Nested Navigation Deep Links
What if your screens are inside tabs?
const linking = {
prefixes: ['myapp://'],
config: {
screens: {
MainTabs: {
screens: {
HomeTab: {
screens: {
Home: 'home',
Details: 'details/:id',
},
},
ProfileTab: {
screens: {
Profile: 'profile',
EditProfile: 'profile/edit',
},
},
},
},
},
},
};
Reading URL Parameters
function ProductScreen({ route }) {
const { productId } = route.params;
return (
<View>
<Text>Product ID: {productId}</Text>
</View>
);
}
// URL: myapp://product/123
// productId will be "123"
graph TD A["📱 User Clicks Link"] --> B["myapp://product/42"] B --> C["App Opens"] C --> D["Navigation Reads Config"] D --> E["Finds &#39;product/:productId&#39;"] E --> F["Opens Product Screen"] F --> G["Passes productId = 42"]
🔐 Auth Flow Navigation
What is It?
Some rooms in your house are private. You need a key to enter! Auth Flow Navigation decides which screens users can see based on whether they’re logged in or not.
The Simple Story
Think of a club with two areas:
- Public Area: Anyone can enter (Login, Signup screens)
- VIP Area: Only members allowed (Home, Profile, Settings)
Auth Flow is the bouncer who checks your membership card!
The Magic Pattern
We show different screens based on login status:
function App() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
return (
<NavigationContainer>
<Stack.Navigator>
{isLoggedIn ? (
// VIP Area - Only for logged in users
<>
<Stack.Screen name="Home" />
<Stack.Screen name="Profile" />
<Stack.Screen name="Settings" />
</>
) : (
// Public Area - For everyone
<>
<Stack.Screen name="Login" />
<Stack.Screen name="Signup" />
<Stack.Screen name="ForgotPassword" />
</>
)}
</Stack.Navigator>
</NavigationContainer>
);
}
Using Context for Auth State
Step 1: Create Auth Context
const AuthContext = React.createContext();
function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const signIn = async (email, password) => {
// Your login logic
const userData = await loginAPI(email, password);
setUser(userData);
};
const signOut = () => {
setUser(null);
};
return (
<AuthContext.Provider
value={{ user, signIn, signOut }}
>
{children}
</AuthContext.Provider>
);
}
Step 2: Use in Navigation
function Navigation() {
const { user } = useContext(AuthContext);
return (
<Stack.Navigator>
{user ? (
<Stack.Screen name="Home" />
) : (
<Stack.Screen name="Login" />
)}
</Stack.Navigator>
);
}
Handling Loading State
What if we’re checking if user is logged in?
function App() {
const [isLoading, setIsLoading] = useState(true);
const [user, setUser] = useState(null);
useEffect(() => {
// Check stored login
checkLoginStatus().then(userData => {
setUser(userData);
setIsLoading(false);
});
}, []);
if (isLoading) {
return <SplashScreen />;
}
return (
<NavigationContainer>
<Stack.Navigator>
{user ? (
<Stack.Screen name="Home" />
) : (
<Stack.Screen name="Login" />
)}
</Stack.Navigator>
</NavigationContainer>
);
}
graph TD A["🚀 App Starts"] --> B{Checking Login...} B --> C["Show Splash Screen"] C --> D{Is User Logged In?} D -->|Yes| E["Show Home, Profile, Settings"] D -->|No| F["Show Login, Signup"] E --> G["User Signs Out"] G --> F F --> H["User Signs In"] H --> E
📝 TypeScript Navigation
What is It?
TypeScript is like having a spell-checker for your code. It catches mistakes before they become bugs!
The Simple Story
Imagine building with LEGO. TypeScript is like having:
- Labels on each LEGO piece
- A guide that tells you which pieces fit together
- Warnings when you try to connect wrong pieces
Why Use TypeScript with Navigation?
Without TypeScript:
// Typo! "Hom" instead of "Home"
navigation.navigate('Hom'); // No error until app crashes!
With TypeScript:
// TypeScript yells: "Hom" is not a valid screen!
navigation.navigate('Hom'); // Error caught immediately!
Setting Up Types
Step 1: Define Your Screen List
// types/navigation.ts
export type RootStackParamList = {
Home: undefined;
Profile: { userId: string };
Product: { productId: number; color?: string };
Settings: undefined;
};
undefined= Screen needs no parameters{ userId: string }= Screen NEEDS userId{ productId: number; color?: string }= productId required, color optional
Step 2: Create Typed Navigator
import {
createStackNavigator
} from '@react-navigation/stack';
import { RootStackParamList } from './types';
const Stack = createStackNavigator<RootStackParamList>();
Step 3: Typed Navigation in Screens
import {
NativeStackScreenProps
} from '@react-navigation/native-stack';
type ProfileProps = NativeStackScreenProps<
RootStackParamList,
'Profile'
>;
function ProfileScreen({ route, navigation }: ProfileProps) {
// TypeScript knows userId is a string!
const { userId } = route.params;
// TypeScript checks this is valid!
navigation.navigate('Product', {
productId: 123
});
}
The useNavigation Hook with Types
import {
useNavigation
} from '@react-navigation/native';
import {
NativeStackNavigationProp
} from '@react-navigation/native-stack';
type NavigationProp = NativeStackNavigationProp<
RootStackParamList
>;
function MyComponent() {
const navigation = useNavigation<NavigationProp>();
// Now TypeScript helps you!
navigation.navigate('Profile', {
userId: 'john123'
});
}
Nested Navigator Types
// Tab Navigator Types
type TabParamList = {
HomeTab: undefined;
ProfileTab: undefined;
};
// Stack inside HomeTab
type HomeStackParamList = {
HomeMain: undefined;
Details: { itemId: number };
};
// Combined for nested navigation
type RootParamList = {
Tabs: NavigatorScreenParams<TabParamList>;
Modal: { message: string };
};
graph TD A["📝 Define Types"] --> B["RootStackParamList"] B --> C["Screen Names"] B --> D["Screen Parameters"] C --> E["TypeScript Validates"] D --> E E --> F["No More Typos!"] E --> G["Correct Params Always!"] E --> H["Better Autocomplete!"]
🎯 Putting It All Together
Here’s how all four concepts work together in a real app:
// types.ts
export type RootStackParamList = {
Login: undefined;
Home: undefined;
Profile: { userId: string };
};
// App.tsx
const Stack = createStackNavigator<RootStackParamList>();
const linking = {
prefixes: ['myapp://'],
config: {
screens: {
Home: 'home',
Profile: 'profile/:userId',
},
},
};
function App() {
const { user } = useAuth();
const isDark = useColorScheme() === 'dark';
return (
<NavigationContainer
theme={isDark ? DarkTheme : LightTheme}
linking={linking}
>
<Stack.Navigator>
{user ? (
<>
<Stack.Screen name="Home" />
<Stack.Screen name="Profile" />
</>
) : (
<Stack.Screen name="Login" />
)}
</Stack.Navigator>
</NavigationContainer>
);
}
🏆 What You’ve Learned
| Concept | What It Does | Real World Example |
|---|---|---|
| Theming | Changes colors/styles | Dark mode toggle |
| Deep Links | Opens exact screens from URLs | Sharing product links |
| Auth Flow | Guards private screens | Login required pages |
| TypeScript | Catches navigation errors | Autocomplete & safety |
💡 Quick Tips
- Always test deep links on real devices
- Use context for auth state, not props
- Create a single types file for all navigation types
- Match theme colors with your brand
🎉 You Did It!
You now understand the four pillars of Advanced Navigation:
- 🎨 Theming - Make your app beautiful
- 🔗 Deep Links - Let users jump anywhere
- 🔐 Auth Flow - Protect private screens
- 📝 TypeScript - Write safer code
Your app is no longer just a house with doors. It’s a smart, secure, beautiful mansion with magical portals! 🏰✨
