Εισαγωγή
Η πλοήγηση είναι, κυριολεκτικά, ο πυρήνας κάθε mobile εφαρμογής. Χωρίς αξιόπιστη πλοήγηση, ακόμα κι αν έχεις φτιάξει κάτι εντυπωσιακό, ο χρήστης δεν θα μπορεί καν να το χρησιμοποιήσει. Στο οικοσύστημα του React Native, η πλοήγηση πέρασε από πολλές φάσεις — manual navigators, configuration objects, πολύπλοκα nesting patterns. Ειλικρινά, ήταν λίγο κουραστικό.
Το Expo Router αλλάζει τα δεδομένα ριζικά. Φέρνει file-based routing στο React Native, παρόμοιο με αυτό που κάνει το Next.js στο web. Αν έχεις δουλέψει με Next.js, θα νιώσεις σαν στο σπίτι σου.
Με την κυκλοφορία του Expo SDK 55 και του Expo Router v7, τα πράγματα γίνονται ακόμα καλύτερα. Αυτόματο deep linking, type-safe routes, native tabs με Material Design 3, Apple Zoom transitions — και όλα αυτά με σημαντικά λιγότερο boilerplate. Λοιπόν, ας δούμε τι ακριβώς μπορείς να κάνεις.
Τι Είναι το Expo Router και Γιατί να το Χρησιμοποιήσεις
File-Based Routing: Η Βασική Ιδέα
Η ιδέα είναι απλή: αντί να ορίζεις routes σε configuration objects (και να ξεχνάς πού βάλες τι), απλά δημιουργείς αρχεία μέσα στον φάκελο src/app. Κάθε αρχείο γίνεται αυτόματα μια οθόνη. Η δομή φακέλων αντικατοπτρίζει τη δομή URL — τόσο στο mobile όσο και στο web.
Δες ένα παράδειγμα:
src/app/
├── _layout.tsx → Root Layout
├── index.tsx → Αρχική οθόνη (/)
├── about.tsx → Σελίδα about (/about)
├── (tabs)/
│ ├── _layout.tsx → Tab Layout
│ ├── home.tsx → Tab: Home (/home)
│ ├── search.tsx → Tab: Search (/search)
│ └── profile.tsx → Tab: Profile (/profile)
└── settings/
├── index.tsx → Settings (/settings)
└── notifications.tsx → Ειδοποιήσεις (/settings/notifications)
Αυτή η δομή δημιουργεί αυτόματα ολόκληρο το σύστημα πλοήγησης. Κανένα configuration. Ούτε μία γραμμή ρύθμισης. Το Expo Router μετατρέπει εσωτερικά τη δομή σε React Navigation configuration, οπότε δεν χάνεις τίποτα σε δυνατότητες.
Expo Router vs React Navigation
Κάτι που πρέπει να ξεκαθαρίσουμε: το Expo Router δεν αντικαθιστά το React Navigation — χτίζεται πάνω σε αυτό. Σκέψου το σαν ένα layer που απλοποιεί τη ρύθμιση, ενώ κάτω χρησιμοποιεί τον ίδιο αξιόπιστο navigation engine.
Τα πλεονεκτήματα που παίρνεις:
- Αυτόματο deep linking: Κάθε route γίνεται accessible μέσω URL αυτόματα — χωρίς χειροκίνητη ρύθμιση.
- Type-safe routes: Στατική τυποποίηση routes σε TypeScript. Δεν μπορείς να κάνεις navigate σε route που δεν υπάρχει (και αυτό σε σώζει πιο συχνά απ' ό,τι νομίζεις).
- Lazy bundling: Στο development, κάθε route φορτώνεται μόνο όταν ζητηθεί — ο κύκλος ανάπτυξης επιταχύνεται αισθητά.
- Καθολική υποστήριξη: Android, iOS και web μοιράζονται την ίδια δομή πλοήγησης.
- Static rendering στο web: Βελτιωμένο SEO μέσω server-side rendering.
Αν ξεκινάς νέο project, η επίσημη σύσταση του Expo είναι ξεκάθαρη: χρησιμοποίησε Expo Router. Αν έχεις ήδη κάτι σε React Navigation, μπορείς να μεταβείς σταδιακά — δεν χρειάζεται να ξαναγράψεις τα πάντα από την αρχή.
Εγκατάσταση και Ρύθμιση
Νέο Project με Expo SDK 55
Ο πιο γρήγορος τρόπος να ξεκινήσεις:
npx create-expo-app@latest MyApp --template default@sdk-55
Αυτό σου δίνει ένα έτοιμο project με React Native 0.83.1, React 19.2, Expo Router v7, και native tabs ήδη ρυθμισμένα. Βασικά, μπορείς να αρχίσεις δουλειά αμέσως.
Εγκατάσταση σε Υπάρχον Project
Αν θέλεις να προσθέσεις Expo Router σε ένα project που υπάρχει ήδη, τα βήματα είναι τα εξής. Πρώτα, εγκατέστησε τα dependencies:
npx expo install expo-router react-native-safe-area-context react-native-screens expo-linking expo-constants expo-status-bar
Μετά, πρόσθεσε το scheme στο app.json:
{
"expo": {
"scheme": "myapp",
"plugins": ["expo-router"]
}
}
Δημιούργησε τον φάκελο src/app και πρόσθεσε το root layout:
// src/app/_layout.tsx
import { Stack } from 'expo-router';
export default function RootLayout() {
return ;
}
Και τέλος, μια βασική αρχική οθόνη:
// src/app/index.tsx
import { View, Text, StyleSheet } from 'react-native';
import { Link } from 'expo-router';
export default function HomeScreen() {
return (
<View style={styles.container}>
<Text style={styles.title}>Καλωσήρθες!</Text>
<Link href="/about">Σχετικά</Link>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
title: { fontSize: 24, fontWeight: 'bold' },
});
Τόσο απλό. Έχεις ήδη ένα λειτουργικό routing σύστημα.
Stack Navigation: Η Βάση της Πλοήγησης
Βασική Ρύθμιση Stack
Το Stack είναι ο πιο θεμελιώδης τύπος πλοήγησης — και πιθανότατα αυτός που θα χρησιμοποιείς περισσότερο. Κάθε νέα οθόνη «σπρώχνεται» πάνω στην προηγούμενη σαν στοίβα, κι ο χρήστης πατάει πίσω για να επιστρέψει. Κλασικό pattern.
// src/app/_layout.tsx
import { Stack } from 'expo-router';
export default function RootLayout() {
return (
<Stack
screenOptions={{
headerStyle: { backgroundColor: '#6200ee' },
headerTintColor: '#fff',
headerTitleStyle: { fontWeight: 'bold' },
}}
>
<Stack.Screen name="index" options={{ title: 'Αρχική' }} />
<Stack.Screen name="details" options={{ title: 'Λεπτομέρειες' }} />
<Stack.Screen
name="modal"
options={{ presentation: 'modal' }}
/>
</Stack>
);
}
Πλοήγηση μεταξύ Οθονών
Έχεις δύο τρόπους να πλοηγηθείς: δηλωτικά με το Link component ή προγραμματικά με το router object. Στην πράξη, θα χρησιμοποιείς και τα δύο, ανάλογα με το context.
// src/app/index.tsx
import { View, Text, Pressable, StyleSheet } from 'react-native';
import { Link, router } from 'expo-router';
export default function HomeScreen() {
const handleNavigate = () => {
// Προγραμματική πλοήγηση
router.push('/details?id=42');
};
return (
<View style={styles.container}>
{/* Δηλωτική πλοήγηση με Link */}
<Link href="/details?id=1" style={styles.link}>
Δες Λεπτομέρειες (Link)
</Link>
{/* Προγραμματική πλοήγηση */}
<Pressable onPress={handleNavigate} style={styles.button}>
<Text style={styles.buttonText}>Δες Λεπτομέρειες (Push)</Text>
</Pressable>
{/* Replace αντί push */}
<Pressable onPress={() => router.replace('/login')} style={styles.button}>
<Text style={styles.buttonText}>Πήγαινε στο Login</Text>
</Pressable>
</View>
);
}
Ένα γρήγορο cheat sheet για τις μεθόδους πλοήγησης:
- router.push(): Σπρώχνει νέα οθόνη στη στοίβα. Ο χρήστης μπορεί να πάει πίσω.
- router.replace(): Αντικαθιστά την τρέχουσα οθόνη. Ιδανικό μετά από login — δεν θέλεις ο χρήστης να πατήσει «πίσω» και να δει ξανά τη φόρμα σύνδεσης.
- router.back(): Επιστρέφει στην προηγούμενη οθόνη.
- router.navigate(): Πλοηγεί σε route, κάνοντας unwind αν υπάρχει ήδη στη στοίβα.
Dynamic Routes
Τα dynamic routes είναι αυτό ακριβώς που φαντάζεσαι — οθόνες με δυναμικές παραμέτρους. Βάζεις αγκύλες στο όνομα αρχείου και τελειώνεις:
// src/app/product/[id].tsx
import { View, Text } from 'react-native';
import { useLocalSearchParams } from 'expo-router';
export default function ProductScreen() {
const { id } = useLocalSearchParams<{ id: string }>();
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Προϊόν ID: {id}</Text>
</View>
);
}
Πλοηγείσαι σε αυτή την οθόνη με router.push('/product/42') ή <Link href="/product/42">. Η παράμετρος id θα πάρει αυτόματα την τιμή "42".
Tab Navigation: Bottom Tabs στο Expo Router
JavaScript Tabs
Τα bottom tabs είναι, ας πούμε, ο «de facto» τρόπος πλοήγησης στα περισσότερα mobile apps. Instagram, Twitter, σχεδόν τα πάντα. Στο Expo Router, δημιουργείς ένα tab layout με μια ομάδα (tabs):
// src/app/(tabs)/_layout.tsx
import { Tabs } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';
export default function TabLayout() {
return (
<Tabs
screenOptions={{
tabBarActiveTintColor: '#6200ee',
tabBarInactiveTintColor: '#888',
headerStyle: { backgroundColor: '#6200ee' },
headerTintColor: '#fff',
}}
>
<Tabs.Screen
name="home"
options={{
title: 'Αρχική',
tabBarIcon: ({ color, size }) => (
<Ionicons name="home" size={size} color={color} />
),
}}
/>
<Tabs.Screen
name="search"
options={{
title: 'Αναζήτηση',
tabBarIcon: ({ color, size }) => (
<Ionicons name="search" size={size} color={color} />
),
}}
/>
<Tabs.Screen
name="profile"
options={{
title: 'Προφίλ',
tabBarIcon: ({ color, size }) => (
<Ionicons name="person" size={size} color={color} />
),
}}
/>
</Tabs>
);
}
Μικρό tip: αν θέλεις κάποιο route να υπάρχει αλλά να μην εμφανίζεται στη tab bar, χρησιμοποίησε href: null:
<Tabs.Screen
name="hidden-screen"
options={{ href: null }}
/>
Native Tabs (SDK 55)
Εδώ τα πράγματα γίνονται ενδιαφέροντα. Το Expo Router v7 φέρνει τα Native Tabs — tabs που χρησιμοποιούν τη native tab bar του κάθε λειτουργικού. Στο Android, ακολουθούν αυτόματα τα Material Design 3 dynamic colors (προσαρμόζονται στα χρώματα που έχει επιλέξει ο χρήστης). Στο iOS, χρησιμοποιούν τον native UITabBarController.
Η διαφορά στο look and feel είναι αμέσως αισθητή.
// src/app/(tabs)/_layout.tsx
import { NativeTabs } from 'expo-router';
export default function TabLayout() {
return (
<NativeTabs>
<NativeTabs.Screen name="index">
<NativeTabs.Screen.Icon md="home" sf="house.fill" />
<NativeTabs.Screen.Label>Αρχική</NativeTabs.Screen.Label>
</NativeTabs.Screen>
<NativeTabs.Screen name="search">
<NativeTabs.Screen.Icon md="search" sf="magnifyingglass" />
<NativeTabs.Screen.Label>Αναζήτηση</NativeTabs.Screen.Label>
</NativeTabs.Screen>
<NativeTabs.Screen name="profile">
<NativeTabs.Screen.Icon md="person" sf="person.fill" />
<NativeTabs.Screen.Label>Προφίλ</NativeTabs.Screen.Label>
<NativeTabs.Screen.Badge>3</NativeTabs.Screen.Badge>
</NativeTabs.Screen>
</NativeTabs>
);
}
Bonus: τα Native Tabs ενσωματώνουν αυτόματα SafeAreaView, scroll-to-top on tap, και native animations. Δηλαδή λιγότερος κώδικας για εσένα.
Drawer Navigation
Ρύθμιση Drawer
Το drawer (το κλασικό πλαϊνό μενού) είναι ιδανικό για apps με πολλές κατηγορίες ή ρυθμίσεις. Χρειάζεσαι μερικές επιπλέον εξαρτήσεις:
npx expo install @react-navigation/drawer react-native-gesture-handler react-native-reanimated react-native-worklets
Κι ύστερα δημιουργείς το drawer layout:
// src/app/(drawer)/_layout.tsx
import { Drawer } from 'expo-router/drawer';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
export default function DrawerLayout() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<Drawer
screenOptions={{
drawerActiveTintColor: '#6200ee',
headerStyle: { backgroundColor: '#6200ee' },
headerTintColor: '#fff',
}}
>
<Drawer.Screen
name="index"
options={{
drawerLabel: 'Αρχική',
title: 'Αρχική Σελίδα',
}}
/>
<Drawer.Screen
name="settings"
options={{
drawerLabel: 'Ρυθμίσεις',
title: 'Ρυθμίσεις',
}}
/>
<Drawer.Screen
name="help"
options={{
drawerLabel: 'Βοήθεια',
title: 'Κέντρο Βοήθειας',
}}
/>
</Drawer>
</GestureHandlerRootView>
);
}
Άνοιγμα Drawer Προγραμματικά
Θέλεις να ανοίξεις το drawer με κουμπί αντί για swipe; Χρησιμοποίησε το useNavigation hook:
import { Pressable, Text } from 'react-native';
import { DrawerActions } from '@react-navigation/native';
import { useNavigation } from 'expo-router';
export default function CustomMenuButton() {
const navigation = useNavigation();
return (
<Pressable
onPress={() => navigation.dispatch(DrawerActions.openDrawer())}
style={{ padding: 10 }}
>
<Text>☰ Μενού</Text>
</Pressable>
);
}
Nesting Navigators: Συνδυασμός Patterns
Στην πραγματικότητα, σχεδόν καμία εφαρμογή δεν χρησιμοποιεί μόνο ένα pattern πλοήγησης. Το κλασικό σενάριο: tabs στο κάτω μέρος, με κάθε tab να έχει τη δική του στοίβα οθονών. Ας δούμε πώς φαίνεται η δομή αρχείων:
src/app/
├── _layout.tsx → Root Stack
├── (tabs)/
│ ├── _layout.tsx → Tab Layout
│ ├── home/
│ │ ├── _layout.tsx → Stack μέσα στο Home tab
│ │ ├── index.tsx → Αρχική
│ │ └── [postId].tsx → Λεπτομέρειες ανάρτησης
│ ├── search/
│ │ ├── _layout.tsx → Stack μέσα στο Search tab
│ │ ├── index.tsx → Αναζήτηση
│ │ └── results.tsx → Αποτελέσματα
│ └── profile.tsx → Προφίλ (χωρίς nested stack)
├── login.tsx → Login (εκτός tabs)
└── modal.tsx → Modal οθόνη
Κάθε tab μπορεί να έχει το δικό του _layout.tsx με ξεχωριστό Stack. Αυτό σημαίνει ότι η πλοήγηση μέσα σε κάθε tab είναι ανεξάρτητη. Ο χρήστης πλοηγείται βαθύτερα σε ένα tab, αλλάζει tab, κι όταν γυρίσει πίσω, η θέση του είναι ακριβώς εκεί που την άφησε.
// src/app/(tabs)/home/_layout.tsx
import { Stack } from 'expo-router';
export default function HomeStack() {
return (
<Stack>
<Stack.Screen name="index" options={{ title: 'Αρχική' }} />
<Stack.Screen name="[postId]" options={{ title: 'Ανάρτηση' }} />
</Stack>
);
}
Deep Linking: Αυτόματη Σύνδεση URL
Πώς Λειτουργεί
Αυτό είναι, κατά τη γνώμη μου, ένα από τα πιο underrated χαρακτηριστικά του Expo Router. Κάθε route είναι αυτόματα deep linkable. Δεν ρυθμίζεις τίποτα. Αν η εφαρμογή σου έχει ένα αρχείο src/app/product/[id].tsx, τότε το URL myapp://product/42 θα ανοίξει τη σωστή οθόνη με id: 42.
Πού είναι χρήσιμο αυτό;
- Push notifications: Ο χρήστης πατάει μια ειδοποίηση → ανοίγει κατευθείαν η σωστή οθόνη.
- Marketing links: Μοίρασε links που ανοίγουν συγκεκριμένο περιεχόμενο.
- E2E testing: Πλοηγήσου κατευθείαν στην οθόνη που θέλεις να δοκιμάσεις — χωρίς να κάνεις tap σε 5 κουμπιά.
- Web sharing: Κάθε οθόνη έχει URL. Απλό.
Custom Scheme και Universal Links
Για custom deep link scheme, πρόσθεσε το scheme στο app.json:
{
"expo": {
"scheme": "myapp"
}
}
Για Universal Links (iOS) και App Links (Android) — δηλαδή κανονικά https:// URLs που ανοίγουν απευθείας την εφαρμογή αντί για τον browser — χρειάζεσαι domain verification:
{
"expo": {
"ios": {
"associatedDomains": ["applinks:myapp.com"]
},
"android": {
"intentFilters": [
{
"action": "VIEW",
"autoVerify": true,
"data": [{ "scheme": "https", "host": "myapp.com", "pathPrefix": "/" }],
"category": ["BROWSABLE", "DEFAULT"]
}
]
}
}
}
Δοκιμή Deep Links
Μπορείς να δοκιμάσεις deep links κατευθείαν από το terminal:
# iOS
npx uri-scheme open myapp://product/42 --ios
# Android
npx uri-scheme open myapp://product/42 --android
Σημαντική σημείωση: τα deep links δεν λειτουργούν στο Expo Go. Χρειάζεσαι development build (npx expo run:ios ή npx expo run:android). Αυτό πιάνει πολλούς απροετοίμαστους, οπότε αξίζει να το θυμάσαι.
Type-Safe Routes
Αν χρησιμοποιείς TypeScript (και ελπίζω να χρησιμοποιείς), αυτό θα σου αρέσει. Το Expo Router μπορεί να δημιουργήσει αυτόματα types για τα routes σου. Αν γράψεις λάθος path, παίρνεις compile-time error αντί για ένα μυστηριώδες runtime crash:
import { router } from 'expo-router';
// ✅ Σωστό — υπάρχει το route
router.push('/product/42');
// ❌ TypeScript error — δεν υπάρχει αυτό το route
router.push('/produc/42'); // Typo! Ο compiler σε σώζει
Για να το ενεργοποιήσεις, πρόσθεσε στο app.json:
{
"expo": {
"experiments": {
"typedRoutes": true
}
}
}
Μετά τρέξε npx expo start και τα types δημιουργούνται αυτόματα. Τόσο απλά.
Νέα Χαρακτηριστικά στο Expo Router v7 (SDK 55)
Νέο Stack API με Components
Αυτή ίσως είναι η πιο ουσιαστική αλλαγή στο Router v7. Αντί να ρυθμίζεις το header μέσω options (που γινόταν λίγο messy σε πιο σύνθετα scenarios), τώρα χρησιμοποιείς composable React components μέσα στην ίδια την οθόνη:
// src/app/article/[id].tsx
import { View, Text } from 'react-native';
import { Stack } from 'expo-router';
export default function ArticleScreen() {
return (
<View style={{ flex: 1 }}>
<Stack.Header>
<Stack.Header.Title>Άρθρο</Stack.Header.Title>
<Stack.Header.SearchBar placeholder="Αναζήτηση..." />
</Stack.Header>
<Text>Περιεχόμενο άρθρου...</Text>
</View>
);
}
Πολύ πιο readable, πολύ πιο React-like.
Stack.Toolbar (iOS)
Το Stack.Toolbar δίνει πρόσβαση στο native iOS toolbar. Τρεις θέσεις: αριστερά, δεξιά στο header, ή στο κάτω μέρος της οθόνης. Υποστηρίζει buttons, menus, custom views, search bars — με ενσωματωμένες animations και liquid glass effect.
import { Stack } from 'expo-router';
export default function EditorScreen() {
return (
<View style={{ flex: 1 }}>
<Stack.Toolbar placement="right">
<Stack.Toolbar.Button
sf="square.and.arrow.up"
onPress={() => share()}
/>
<Stack.Toolbar.Button
sf="heart"
onPress={() => favorite()}
/>
</Stack.Toolbar>
<Stack.Toolbar placement="bottom">
<Stack.Toolbar.Button sf="bold" onPress={() => toggleBold()} />
<Stack.Toolbar.Spacer />
<Stack.Toolbar.Button sf="textformat" onPress={() => format()} />
</Stack.Toolbar>
<Text>Επεξεργαστής κειμένου</Text>
</View>
);
}
Apple Zoom Transitions
Τα Apple Zoom transitions φέρνουν native shared element transitions χωρίς κανένα configuration. Στο iOS, ενεργοποιούνται αυτόματα κι δίνουν εντυπωσιακά gesture-driven animations κατά τη μετάβαση μεταξύ οθονών. Ο χρήστης νιώθει πραγματικά native εμπειρία.
SplitView για iPad (Πειραματικό)
Τέλος, το Router v7 εισάγει πειραματική υποστήριξη για SplitView. Ιδανικό για iPad και μεγάλες οθόνες. Στο iPhone κάνει αυτόματα collapse σε single column. Αν φτιάχνεις app που πρέπει να δουλεύει και σε tablet, αυτό είναι πολύ ενθαρρυντικό βήμα.
Βέλτιστες Πρακτικές
Μετά από αρκετή χρήση του Expo Router, αυτά είναι τα πράγματα που κάνουν τη μεγαλύτερη διαφορά:
- Κράτα τον φάκελο
src/appκαθαρό: Μόνο route files. Components, hooks, utilities πάνε σεsrc/components,src/hooks,src/utils. Μην τον μετατρέψεις σε «χωματερή». - Χρησιμοποίησε groups: Τα groups
(groupName)δεν προστίθενται στο URL αλλά οργανώνουν τον κώδικα. Ιδανικά για auth flows. - Ενεργοποίησε typed routes: Σοβαρά, κάντο. Θα σε σώσει από bugs.
- Μη βάζεις πολύπλοκη λογική στα layouts: Τα
_layout.tsxπρέπει να ορίζουν μόνο τη δομή πλοήγησης, τίποτα παραπάνω. - Χρησιμοποίησε
router.replace()μετά από login: Κανένας δεν θέλει να πατήσει «πίσω» και να ξαναδεί τη φόρμα σύνδεσης. - Δοκίμασε deep links νωρίς: Μην τα αφήνεις για το τέλος. Φτιάξε development build νωρίς και δοκίμασέ τα σε πραγματική συσκευή.
Συχνές Ερωτήσεις (FAQ)
Μπορώ να χρησιμοποιήσω React Navigation μαζί με Expo Router;
Ναι, φυσικά. Το Expo Router χτίζεται πάνω στο React Navigation, οπότε μπορείς να χρησιμοποιήσεις οποιοδήποτε React Navigation API. Στην πράξη, τα Stack, Tabs, Drawer του Expo Router είναι wrappers πάνω στα αντίστοιχα React Navigation components.
Πώς κάνω authentication flow με Expo Router;
Χρησιμοποίησε route groups. Φτιάξε ένα group (auth) με τα login/register screens κι ένα group (app) με τα protected screens. Στο root layout, έλεγξε αν ο χρήστης είναι authenticated κι αν όχι, κάνε redirect με router.replace().
Λειτουργούν τα deep links στο Expo Go;
Όχι. Το Expo Go υποστηρίζει μόνο exp:// links. Για custom deep links, χρειάζεσαι development build (npx expo run:ios ή npx expo run:android). Αυτό μπερδεύει πολλούς αρχάριους, αλλά δυστυχώς δεν υπάρχει workaround.
Τι είναι τα Native Tabs και σε τι διαφέρουν;
Τα Native Tabs χρησιμοποιούν τη native tab bar του OS αντί JavaScript rendering. Στο Android ακολουθούν Material Design 3 dynamic colors, στο iOS τον UITabBarController. Η διαφορά; Πιο φυσική εμφάνιση, πιο smooth performance, πιο «σαν κανονικό native app».
Πώς κάνω migration από React Navigation στο Expo Router;
Βήμα-βήμα: πρώτα σπάσε τα screen components σε ξεχωριστά αρχεία. Μετά δημιούργησε τη δομή φακέλων στο src/app που αντιστοιχεί στα routes σου. Πρόσθεσε τα _layout.tsx με τους navigators. Τέλος, αντικατέστησε τα navigation.navigate() με router.push() ή <Link>. Δεν χρειάζεται να γίνει σε μια μέρα — κάντο σταδιακά.