Expo Router i React Native Nawigacja
Expo Router v3 (file-based, universal), React Navigation v6 (Stack/Tab/Drawer), typed navigation, EAS i React Native Web.
6 opcji nawigacji i styling w React Native
Expo Router, React Navigation, Expo+Next.js, NativeWind i Tamagui — typ, platforma i kiedy użyć.
| Narzędzie | Typ | Platforma | Routing | Kiedy |
|---|---|---|---|---|
| Expo Router v3 | File-based (Universal) | iOS + Android + Web | app/ directory | Nowe projekty Expo, universal apps |
| React Navigation v6 | Imperative | iOS + Android | createXNavigator() | Bare React Native, dojrzałe projekty |
| React Native Navigation | Native tabs/stacks | iOS + Android | Wycofywany | Legacy Wix projects (unikaj) |
| Expo Router + Next.js | Universal routing | iOS + Android + Web | Solito/universal | Full universal app, shared codebase |
| NativeWind v4 | Styling (Tailwind) | iOS + Android + Web | Brak | Tailwind dla RN, NativeWind+Expo Router |
| Tamagui | Universal UI Kit | iOS + Android + Web | Brak | Design system universal, performance |
Często zadawane pytania
Co to jest Expo Router i jak różni się od React Navigation?
Expo Router (v3, 2023): file-based routing dla React Native + Web. Jak Next.js App Router ale dla mobile. Oparty na React Navigation pod spodem. Strukturacja: app/_layout.tsx — root layout. app/index.tsx — ekran główny. app/(tabs)/home.tsx — tab routing. app/users/[id].tsx — dynamiczne trasy. Zalety Expo Router: automatyczny deep linking. Routing oparty na plikach — intuicyjny. Universal: iOS, Android i Web z jednym kodem. TypeScript types dla parametrów nawigacji. React Navigation (v6): imperative routing. Konfiguracja w kodzie (nie plikach). NavigationContainer. createStackNavigator, createBottomTabNavigator. Stack.Navigator, Stack.Screen. Bardziej elastyczny ale verbose. Expo Router vs React Navigation: Expo Router — file-based, universal, nowszy. React Navigation — dojrzalszy, więcej tutoriali, bare RN. Expo Router używa React Navigation pod spodem. Migracja: stopniowa możliwa. Expo SDK: Expo Go — szybki development. EAS Build — cloud builds. EAS Submit — submission do App Store. EAS Update — OTA updates (bez App Store review). Expo Router setup: npx create-expo-app@latest. Template: blank (TypeScript). app directory convention. Metro bundler (Expo). TypeScript path aliases: babel-plugin-module-resolver lub tsconfig paths. @ prefix. Expo constants: expo-constants. Constants.expoConfig.name. Environment-specific config.
React Navigation v6 — Stack, Tab i Drawer navigatory?
React Navigation v6: NavigationContainer wraps całą aplikację. const Stack = createNativeStackNavigator(). Stack.Navigator: Stack.Screen name='Home' component={HomeScreen}. createBottomTabNavigator: tabBarIcon prop. tabBarLabel. Tab.Screen options={{title: 'Home', tabBarIcon: ({color}) => Icon}}. createDrawerNavigator: Drawer.Navigator, Drawer.Screen. createMaterialTopTabNavigator: swipeable tabs. Typed navigation (TypeScript): type RootStackParamList = {'Home': undefined, 'UserDetail': {userId: string}, 'Settings': {tab: 'account' | 'notifications'}}. const Stack = createNativeStackNavigator(). Props type: NativeStackScreenProps. useNavigation: const nav = useNavigation(). nav.navigate('Home'). nav.push('UserDetail', {userId: '123'}). nav.goBack(). nav.replace('Home'). useRoute: const route = useRoute(). route.params.userId. Nested navigators: Tab zawiera Stack. Stack zawiera Modal. Drawer zawiera Tab + Stack. Deep linking config: linking.config. path -> screen mapping. Universal links (iOS) + App Links (Android). Screens: react-native-screens. Natywne kontenerki dla ekranów. Poprawa wydajności. Wymagane: enableScreens() w index.js. Header customization: options={{headerTitle: () => CustomHeader, headerRight: () => Button, headerStyle: {backgroundColor: '#fff'}}}. gestureEnabled: true (swipe back iOS). Modal presentation: presentation: 'modal'. cardOverlayEnabled. Animacje przejść: transitionSpec, cardStyleInterpolator.
Expo Router v3 — file-based routing, layouts i grupy?
Expo Router v3 struktura: app/(tabs)/_layout.tsx — Tab layout. app/(tabs)/index.tsx — tab home. app/(tabs)/settings.tsx — tab settings. app/modal.tsx — modal screen. app/users/[id].tsx — dynamic segment. app/users/[id]/posts.tsx — nested dynamic. _layout.tsx: export default function Layout() {return Tabs (lub Stack, Drawer)}. Grupy routingowe: (auth) — nie wpływa na URL. (tabs) — tab group. Parallel routes: (modal) + (app). Expo Router Link: import {Link} from 'expo-router'. Link href='/users/123'. Link href={{pathname: '/users/[id]', params: {id: '123'}}}. useLocalSearchParams: const {id} = useLocalSearchParams(). Typed routes (Expo Router v3+): require('expo-router') provides typed href. Automatyczne typy z plików. useSegments: const segments = useSegments(). Sprawdź czy w auth group. Guards: if (!user && !segments[0]?.startsWith('(auth)')) {router.replace('/(auth)/login')}. Shared layouts: dzieci inherentują layout. Stack w layoutcie. Stack.Screen options={{title: 'Custom Title'}} wewnątrz ekranu. API Routes (Expo Router v3): app/api/hello+api.ts. export function GET(req) {return Response.json({hello: 'world'})}. Server-side logic dla universal apps. EAS Update: OTA updates bez App Store. expo-updates package. Updates.fetchUpdateAsync(). Channel-based: production, preview, development. Expo Modules: natywne moduły w Swift/Kotlin. expo-module-scripts. Możesz pisać natywne moduły z TypeScript API.
Nawigacja a stan aplikacji — integracja z Zustand i React Query?
State management w React Native: Zustand — najlepszy wybór 2024. Prosty, zero boilerplate. MMKV jako persist storage (zamiast AsyncStorage). Zustand + MMKV: import {MMKV} from 'react-native-mmkv'. const storage = new MMKV(). const mmkvStorage = {getItem: (k) => storage.getString(k), setItem: (k, v) => storage.set(k, v), removeItem: (k) => storage.delete(k)}. persist(store, {storage: createJSONStorage(() => mmkvStorage)}). React Query w React Native: QueryClientProvider. focusManager.setEventListener — AppState based refetch. NetworkStatus: NetInfo (@react-native-community/netinfo). onlineManager.setEventListener. Background fetch: expo-background-fetch + expo-task-manager. Fetch updates w tle. Push Notifications: expo-notifications. Permissions, tokens, local + remote. Clerk, Firebase, OneSignal dla push. Navigation + Auth flow: Stack.Screen options={{headerShown: false}} dla auth screens. useEffect([user]) -> navigation.reset. Expo Router guard pattern: (auth) group dla unauthenticated. (app) group dla authenticated. Redirect w _layout.tsx bazując na auth state. Deep linking + notifications: notification tap -> navigate to screen. Linking.openURL dla universal links. expo-router/entry-classic dla custom linking. React Navigation Events: useFocusEffect — refetch przy focus. useIsFocused. navigation.addListener('focus', handler). Performance: React Native Skia — zaawansowany rendering. React Native Reanimated v3 — smooth animations. Gesture Handler — natywne gesty. Flashlist zamiast FlatList (szybsza). @shopify/flash-list.
React Native vs React Native Web — universal apps w 2024?
React Native Web (RNW): React Native komponenty na web. View -> div, Text -> span. StyleSheet -> CSS-in-JS. Expo Router native + web w jednym repozytorium. Universal app stack: Expo Router (routing). React Native Web (UI). Solito (navigation helpers). Tamagui lub NativeWind (styling). Tamagui: UI kit dla RN + Web. Tokeny design systemu. Kompilacja: generuje CSS lub native StyleSheet. Wydajność lepsza niż inline styles. NativeWind (Tailwind dla RN): Tailwind classes w React Native. StyleSheet.create pod spodem. Natywne + Web. Solito: navigation helper dla RN + Next.js. useRouter() cross-platform. createParam() dla shared params. Turborepo + Expo + Next.js: packages/ui — shared components. apps/next — Next.js web. apps/expo — Expo mobile. Shared code: utils, types, hooks, stores. Różnice RN vs Web: brak DOM. Brak CSS (StyleSheet). Flexbox domyślnie. Natywne komponenty (TouchableOpacity, Pressable). Platform.select({ios: ..., android: ..., web: ...}). Platform.OS checks. Ograniczenia: RNW nie wspiera wszystkich RN libraries. react-native-maps — nie na web. expo-camera — ograniczone na web. Hybrydowe rozwiązanie: Capacitor — embed web app w natywnym kontenerze. ionic capacitor. Cordova (stary). Nie RN. Expo + Capacitor: nie jest oficjalnie wspierane. Kiedy universal app: startup, małe teams, shared logic. Kiedy oddzielne: max performance, native UX critical.
Powiązane artykuły
Skontaktuj się z nami
Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.
Wyślij zapytanie
Telefon
+48 790 814 814
Pon-Pt: 9:00 - 18:00
adam@fotz.pl
Odpowiadamy w ciągu 24h
Adres
Plac Wolności 16
61-739 Poznań
Godziny pracy
Wolisz porozmawiać?
Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.
Zadzwoń teraz