🧭 Navigation Hooks in React Native
The Story of the Smart Tour Guide
Imagine you’re visiting a huge museum with hundreds of rooms. You have a smart tour guide robot that knows:
- Which room you’re in right now 📍
- When you enter or leave a room 🚪
- How to take you to any room you want 🗺️
- What special items are in each room 🎁
React Native Navigation Hooks are like that smart tour guide for your app!
🌟 What Are Navigation Hooks?
Navigation Hooks are special helpers that tell your app screens important information about where the user is and how to move around.
Think of your app like a house:
- Screens = Rooms in the house
- Navigation = Walking between rooms
- Hooks = Smart sensors and tools in each room
📍 Navigation State
What is Navigation State?
Navigation State is like a detailed map that shows:
- All the rooms (screens) in your app
- Which room you’re currently in
- The path you took to get there
- Breadcrumbs of where you’ve been
Simple Example
// Navigation State looks like this:
const state = {
routes: [
{ name: 'Home', key: 'home-1' },
{ name: 'Profile', key: 'profile-2' },
{ name: 'Settings', key: 'settings-3' }
],
index: 2 // Currently on Settings
};
What This Means:
- You started at Home 🏠
- Then went to Profile 👤
- Now you’re at Settings ⚙️
- The
index: 2points to Settings (counting starts at 0!)
Real Life Use
function MyScreen() {
const state = navigation.getState();
console.log('Current screen:',
state.routes[state.index].name);
// Output: "Settings"
}
🎯 useFocusEffect Hook
The “Room Entry Alarm”
Imagine a motion sensor that does something special EVERY TIME you walk into a room:
- Turns on the lights ✨
- Plays welcome music 🎵
- Fetches fresh data 📊
That’s useFocusEffect!
Why Not Just useEffect?
| useEffect | useFocusEffect |
|---|---|
| Runs when screen first loads | Runs EVERY time screen gets focus |
| Doesn’t know about navigation | Knows when you come back to screen |
| Like a one-time setup | Like a “welcome back” greeting |
Simple Example
import { useFocusEffect } from
'@react-navigation/native';
import { useCallback } from 'react';
function ProfileScreen() {
useFocusEffect(
useCallback(() => {
// This runs when screen is focused
console.log('Welcome to Profile!');
fetchUserData();
// This runs when leaving screen
return () => {
console.log('Goodbye from Profile!');
};
}, [])
);
return <Text>Profile Screen</Text>;
}
Real Life Scenario
Problem: You’re on a shopping cart screen. You go to add more items, then come back. The cart should refresh!
function CartScreen() {
const [items, setItems] = useState([]);
useFocusEffect(
useCallback(() => {
// Fetch fresh cart data every time
// user comes to this screen
loadCartItems().then(setItems);
}, [])
);
return (
<View>
<Text>Cart: {items.length} items</Text>
</View>
);
}
👁️ useIsFocused Hook
The “Am I Being Watched?” Sensor
This hook is like a simple light switch that tells you:
- ON (true): This screen is currently visible
- OFF (false): User is looking at another screen
Simple Example
import { useIsFocused } from
'@react-navigation/native';
function VideoScreen() {
const isFocused = useIsFocused();
return (
<View>
{isFocused ? (
<Video playing={true} />
) : (
<Text>Video paused...</Text>
)}
</View>
);
}
Why This is Useful
Without useIsFocused:
- Video keeps playing when you go to another screen 🔊
- Music doesn’t stop when navigating away 🎵
- Timers keep running in the background ⏱️
With useIsFocused:
- Video pauses automatically when you leave 🔇
- Resources are saved when screen isn’t visible 💪
- Better battery life! 🔋
Comparison with useFocusEffect
graph TD A["useIsFocused"] --> B["Returns true/false"] A --> C["Updates on every render"] A --> D["Good for conditional UI"] E["useFocusEffect"] --> F["Runs callback function"] E --> G["Runs on focus change"] E --> H["Good for side effects"]
🚀 useNavigation Hook
Your Personal Teleporter
useNavigation gives you the power to move between screens from anywhere in your app!
It’s like having a magic remote control that can:
- 📺 Go to any screen (navigate)
- ⬅️ Go back to the previous screen (goBack)
- 🔄 Replace current screen (replace)
- 🏠 Go to the first screen (popToTop)
Simple Example
import { useNavigation } from
'@react-navigation/native';
function HomeScreen() {
const navigation = useNavigation();
return (
<View>
<Button
title="Go to Profile"
onPress={() =>
navigation.navigate('Profile')
}
/>
<Button
title="Go to Settings"
onPress={() =>
navigation.navigate('Settings')
}
/>
</View>
);
}
All the Magic Buttons
function MyComponent() {
const navigation = useNavigation();
// Go to a screen
navigation.navigate('ScreenName');
// Go to screen with data
navigation.navigate('Profile', {
userId: 123
});
// Go back one screen
navigation.goBack();
// Go back to the very first screen
navigation.popToTop();
// Replace current screen
navigation.replace('NewScreen');
// Reset entire navigation
navigation.reset({
index: 0,
routes: [{ name: 'Home' }],
});
}
Why Use This Hook?
Problem: Your button component is deep inside many other components. How does it navigate?
graph TD A["Screen"] --> B["Header"] B --> C["MenuBar"] C --> D["ProfileButton"] D --> E["🤔 How to navigate?"]
Solution: useNavigation works anywhere!
// Deep inside your app structure
function ProfileButton() {
const navigation = useNavigation();
return (
<TouchableOpacity
onPress={() =>
navigation.navigate('Profile')
}
>
<Text>👤</Text>
</TouchableOpacity>
);
}
📦 useRoute Hook
The Package Delivery Person
When you navigate to a screen, you can send packages of data along with it. useRoute is how the screen opens those packages!
Simple Example
Sending the package:
// From HomeScreen
navigation.navigate('ProductDetail', {
productId: 42,
productName: 'Super Widget',
price: 29.99
});
Opening the package:
import { useRoute } from
'@react-navigation/native';
function ProductDetailScreen() {
const route = useRoute();
// Unpack the data!
const { productId, productName, price } =
route.params;
return (
<View>
<Text>Product: {productName}</Text>
<Text>ID: {productId}</Text>
<Text>Price: ${price}</Text>
</View>
);
}
What’s Inside Route?
const route = useRoute();
console.log(route);
// {
// key: 'ProductDetail-abc123',
// name: 'ProductDetail',
// params: {
// productId: 42,
// productName: 'Super Widget',
// price: 29.99
// }
// }
Real Life Scenario
Chat App Example:
// Chat list screen
function ChatListScreen() {
const navigation = useNavigation();
const openChat = (friend) => {
navigation.navigate('ChatRoom', {
friendId: friend.id,
friendName: friend.name,
friendAvatar: friend.avatar
});
};
return (
<FlatList
data={friends}
renderItem={({ item }) => (
<TouchableOpacity
onPress={() => openChat(item)}
>
<Text>{item.name}</Text>
</TouchableOpacity>
)}
/>
);
}
// Chat room screen
function ChatRoomScreen() {
const route = useRoute();
const { friendName, friendAvatar } =
route.params;
return (
<View>
<Image source={{ uri: friendAvatar }} />
<Text>Chatting with {friendName}</Text>
{/* Chat messages here */}
</View>
);
}
🔄 Putting It All Together
Here’s how all four hooks work together in a real app:
import {
useNavigation,
useRoute,
useIsFocused,
useFocusEffect
} from '@react-navigation/native';
import { useCallback, useState } from 'react';
function UserProfileScreen() {
// 📦 Get params passed to this screen
const route = useRoute();
const { userId } = route.params;
// 🚀 Get navigation controls
const navigation = useNavigation();
// 👁️ Check if screen is visible
const isFocused = useIsFocused();
// 🔄 State for user data
const [user, setUser] = useState(null);
// 🎯 Fetch data when screen is focused
useFocusEffect(
useCallback(() => {
fetchUser(userId).then(setUser);
return () => {
// Cleanup when leaving
setUser(null);
};
}, [userId])
);
return (
<View>
{user && (
<>
<Text>{user.name}</Text>
{/* Only show live status if focused */}
{isFocused && (
<LiveStatusBadge userId={userId} />
)}
<Button
title="Edit Profile"
onPress={() =>
navigation.navigate('EditProfile', {
userId: userId
})
}
/>
</>
)}
</View>
);
}
🎯 Quick Summary
graph TD A["🧭 Navigation Hooks"] --> B["📍 Navigation State"] A --> C["🎯 useFocusEffect"] A --> D["👁️ useIsFocused"] A --> E["🚀 useNavigation"] A --> F["📦 useRoute"] B --> B1["Map of all screens"] C --> C1["Run code on focus/blur"] D --> D1["true/false visibility"] E --> E1["Move between screens"] F --> F1["Get passed data"]
| Hook | What It Does | When to Use |
|---|---|---|
| Navigation State | Shows screen history | Debug, custom back behavior |
| useFocusEffect | Runs on focus/blur | Fetch data, start/stop timers |
| useIsFocused | Returns true/false | Conditional rendering |
| useNavigation | Navigate anywhere | Buttons, deep components |
| useRoute | Get passed params | Read data on arrival |
🌟 You Did It!
Now you understand the four superpowers of React Native Navigation:
- See where you are (Navigation State)
- React to arrivals and departures (useFocusEffect)
- Know if you’re being watched (useIsFocused)
- Teleport anywhere (useNavigation)
- Open your packages (useRoute)
You’re now ready to build apps where users can smoothly travel between screens like a pro! 🚀
