# Tworzenie Aplikacji React Native w 2026: Kompletny Przewodnik i Pytania Rekrutacyjne > Poznaj tworzenie aplikacji React Native w 2026 roku z Nową Architekturą, JSI, Fabric i TurboModules. Praktyczny tutorial z przykładami kodu i pytaniami na rozmowę kwalifikacyjną. - Published: 2026-09-06 - Updated: 2026-09-06 - Author: Anthony Fillion-Maillet - Reading time: 5 min --- Tworzenie aplikacji React Native w 2026 roku przeszło fundamentalną transformację wraz z wersją 0.87, która wprowadza Nową Architekturę jako jedyną obsługiwaną opcję. Stary bridge, który serializował każde wywołanie JavaScript-do-native jako JSON, został całkowicie usunięty i zastąpiony przez JSI (JavaScript Interface) umożliwiający bezpośrednią, synchroniczną komunikację. > **Co się zmieniło w React Native 0.87** > > React Native 0.87 czyni Nową Architekturę obowiązkową. Stary bridge został całkowicie usunięty. Renderowanie złożonych list działa o 43% szybciej, spadki klatek podczas przewijania zmniejszyły się o 95%, a wykorzystanie pamięci spadło o 33% w testach wydajnościowych. ## Zrozumienie JSI i Nowej Architektury JSI (JavaScript Interface) zastępuje asynchroniczny bridge bezpośrednimi wiązaniami C++ między JavaScript a kodem natywnym. Zamiast serializować dane do JSON, przekazywać je przez kolejkę komunikatów i deserializować po drugiej stronie, JSI pozwala JavaScript przechowywać referencje do obiektów natywnych i wywoływać ich metody bezpośrednio. Ta zmiana architektoniczna umożliwia trzy kluczowe możliwości: synchroniczne wywołania natywne, współdzielone posiadanie obiektów między warstwami JavaScript i natywną oraz leniwe ładowanie modułów natywnych. ```typescript // NativeUserModule.ts import { TurboModuleRegistry, TurboModule } from 'react-native'; export interface Spec extends TurboModule { getUserProfile(userId: string): Promise<{ id: string; name: string; email: string; }>; // Wywołanie synchroniczne - możliwe tylko z JSI getDeviceLocale(): string; } export default TurboModuleRegistry.getEnforcing('UserModule'); ``` Metoda `getDeviceLocale()` zwraca wynik natychmiast bez oczekiwania na Promise. Było to niemożliwe ze starym bridge, gdzie każde wywołanie natywne wymagało asynchronicznej serializacji. ## Budowanie Komponentu Produkcyjnego z Fabric Fabric to nowy system renderowania działający obok JSI. Zarządza drzewem UI w C++ i synchronizuje się bezpośrednio z wątkiem JavaScript, eliminując "zacinanie się UI", które występowało gdy stary bridge pozostawał w tyle podczas szybkich aktualizacji. ```typescript // ProductCard.tsx import React, { memo, useCallback } from 'react'; import { View, Text, Image, Pressable, StyleSheet, } from 'react-native'; import Animated, { useSharedValue, useAnimatedStyle, withSpring, } from 'react-native-reanimated'; interface Product { id: string; name: string; price: number; imageUrl: string; inStock: boolean; } interface ProductCardProps { product: Product; onPress: (id: string) => void; } const AnimatedPressable = Animated.createAnimatedComponent(Pressable); export const ProductCard = memo(function ProductCard({ product, onPress, }: ProductCardProps) { const scale = useSharedValue(1); const animatedStyle = useAnimatedStyle(() => ({ transform: [{ scale: scale.value }], })); const handlePressIn = useCallback(() => { scale.value = withSpring(0.95); }, [scale]); const handlePressOut = useCallback(() => { scale.value = withSpring(1); }, [scale]); const handlePress = useCallback(() => { onPress(product.id); }, [onPress, product.id]); return ( {product.name} {product.price.toFixed(2)} zł {!product.inStock && ( Brak w magazynie )} ); }); const styles = StyleSheet.create({ card: { backgroundColor: '#ffffff', borderRadius: 12, overflow: 'hidden', marginHorizontal: 8, marginVertical: 4, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 3, }, image: { width: '100%', height: 160, }, content: { padding: 12, }, name: { fontSize: 16, fontWeight: '600', color: '#1a1a1a', marginBottom: 4, }, price: { fontSize: 18, fontWeight: '700', color: '#2563eb', }, outOfStock: { fontSize: 12, color: '#dc2626', marginTop: 4, }, }); ``` Ten komponent używa `react-native-reanimated`, który uruchamia animacje na wątku UI przez JSI. Hooki `useSharedValue` i `useAnimatedStyle` komunikują się bezpośrednio z kodem natywnym bez przechodzenia przez bridge. ## Zarządzanie Stanem z TanStack Query Stan serwera w aplikacjach React Native korzysta z dedykowanych narzędzi. [TanStack Query](https://tanstack.com/query/latest) obsługuje cache'owanie, odświeżanie w tle i optymistyczne aktualizacje bez wymagania globalnego kontenera stanu. ```typescript // hooks/useProducts.ts import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; interface Product { id: string; name: string; price: number; imageUrl: string; inStock: boolean; } const API_BASE = 'https://api.example.com'; async function fetchProducts(category?: string): Promise { const url = category ? `${API_BASE}/products?category=${category}` : `${API_BASE}/products`; const response = await fetch(url); if (!response.ok) { throw new Error('Nie udało się pobrać produktów'); } return response.json(); } export function useProducts(category?: string) { return useQuery({ queryKey: ['products', category], queryFn: () => fetchProducts(category), staleTime: 5 * 60 * 1000, // 5 minut gcTime: 30 * 60 * 1000, // 30 minut }); } export function useToggleStock() { const queryClient = useQueryClient(); return useMutation({ mutationFn: async (productId: string) => { const response = await fetch(`${API_BASE}/products/${productId}/toggle-stock`, { method: 'POST', }); if (!response.ok) { throw new Error('Nie udało się zaktualizować stanu magazynowego'); } return response.json(); }, // Optymistyczna aktualizacja onMutate: async (productId) => { await queryClient.cancelQueries({ queryKey: ['products'] }); const previousProducts = queryClient.getQueryData(['products']); queryClient.setQueryData(['products'], (old) => old?.map((p) => p.id === productId ? { ...p, inStock: !p.inStock } : p ) ); return { previousProducts }; }, onError: (_err, _productId, context) => { if (context?.previousProducts) { queryClient.setQueryData(['products'], context.previousProducts); } }, onSettled: () => { queryClient.invalidateQueries({ queryKey: ['products'] }); }, }); } ``` Callback `onMutate` wykonuje optymistyczną aktualizację przed odpowiedzią serwera. Jeśli mutacja się nie powiedzie, `onError` przywraca poprzedni stan. Ten wzorzec zapewnia natychmiastową reakcję UI przy zachowaniu spójności danych. ## Nawigacja z Expo Router Expo Router zapewnia nawigację opartą na plikach dla React Native, podobnie jak Next.js App Router. Struktura plików automatycznie definiuje trasy. ```typescript // app/(tabs)/_layout.tsx import { Tabs } from 'expo-router'; import { Home, Search, ShoppingCart, User } from 'lucide-react-native'; export default function TabsLayout() { return ( ( ), }} /> ( ), }} /> ( ), }} /> ( ), }} /> ); } ``` Dynamiczne trasy używają notacji nawiasów kwadratowych. Plik w `app/product/[id].tsx` obsługuje dowolną ścieżkę `/product/123`: ```typescript // app/product/[id].tsx import { useLocalSearchParams } from 'expo-router'; import { View, Text, ActivityIndicator } from 'react-native'; import { useQuery } from '@tanstack/react-query'; export default function ProductDetailScreen() { const { id } = useLocalSearchParams<{ id: string }>(); const { data: product, isLoading, error } = useQuery({ queryKey: ['product', id], queryFn: () => fetchProduct(id), enabled: !!id, }); if (isLoading) { return ( ); } if (error || !product) { return ( Nie znaleziono produktu ); } return ( {product.name} {product.price.toFixed(2)} zł ); } ``` ## Popularne Pytania Rekrutacyjne o Architekturę React Native Rozmowy kwalifikacyjne na stanowiska React Native w 2026 roku koncentrują się głównie na Nowej Architekturze. Poniższe pytania pojawiają się często. > **Obszary Fokusowe na Rozmowach** > > Rekruterzy oczekują, że kandydaci potrafią wyjaśnić JSI, Fabric i TurboModules na poziomie koncepcyjnym. Zapamiętywanie składni jest mniej istotne niż zrozumienie, dlaczego architektura się zmieniła i jakie problemy rozwiązuje. **Pytanie: Czym jest JSI i dlaczego React Native go przyjął?** JSI (JavaScript Interface) to warstwa C++, która pozwala JavaScript przechowywać referencje do obiektów natywnych i bezpośrednio wywoływać ich metody. Stary bridge serializował każde wywołanie do JSON, kolejkował je asynchronicznie i deserializował po stronie natywnej. To dodawało opóźnienia i uniemożliwiało operacje synchroniczne. Dzięki JSI funkcja JavaScript może wywołać metodę natywną i otrzymać wynik w tej samej klatce. Umożliwia to funkcje takie jak synchroniczne pomiary układu i bezpośrednia manipulacja widokami natywnymi. **Pytanie: Czym Fabric różni się od starego renderera?** Fabric to system renderowania w C++, który utrzymuje drzewo UI w kodzie natywnym zamiast w JavaScript. Stary renderer przechowywał shadow tree w JavaScript i wysyłał partie aktualizacji przez bridge. Zalety Fabric: - Synchroniczne obliczenia układu przez JSI - Wsparcie dla concurrent rendering (funkcje React 18 działają poprawnie) - Lepsze zarządzanie pamięcią ze współdzielonym posiadaniem między JS a native - Zmniejszony narzut serializacji **Pytanie: Czym są TurboModules?** TurboModules to zamiennik Native Modules. Kluczowe różnice: 1. **Leniwe ładowanie**: TurboModules ładują się dopiero przy pierwszym dostępie, skracając czas uruchamiania 2. **Bezpieczeństwo typów**: CodeGen generuje type-safe wiązania ze specyfikacji TypeScript 3. **Metody synchroniczne**: TurboModules mogą eksponować funkcje synchroniczne gdy jest to potrzebne 4. **Bezpośredni dostęp do JSI**: Brak serializacji przez bridge **Pytanie: Kiedy użyć synchronicznej metody natywnej?** Synchroniczne metody natywne nadają się do operacji, które: - Kończą się w mikrosekundach (odczyt locale urządzenia, sprawdzenie statusu uprawnień) - Celowo blokują UI (potwierdzenie modalne przed nawigacją) - Zwracają wartości potrzebne do natychmiastowego renderowania Należy unikać metod synchronicznych dla: - Żądań sieciowych - Operacji I/O na plikach wykraczających poza małe odczyty - Zapytań do bazy danych - Każdej operacji przekraczającej 16ms (blokuje klatkę) Więcej pytań rekrutacyjnych o React Native znajduje się w [module networking i API](/technologies/react-native/interview-questions/rn-networking-api) oraz [sekcji modułów natywnych](/technologies/react-native/interview-questions/rn-native-modules). ## Testowanie Komponentów React Native React Native Testing Library dostarcza narzędzia do testowania komponentów tak, jak użytkownicy z nimi interagują, skupiając się na dostępności i zachowaniu zamiast szczegółów implementacji. ```typescript // __tests__/ProductCard.test.tsx import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react-native'; import { ProductCard } from '../components/ProductCard'; const mockProduct = { id: 'prod-1', name: 'Słuchawki Bezprzewodowe', price: 149.99, imageUrl: 'https://example.com/headphones.jpg', inStock: true, }; describe('ProductCard', () => { it('wyświetla informacje o produkcie', () => { const onPress = jest.fn(); render(); expect(screen.getByText('Słuchawki Bezprzewodowe')).toBeOnTheScreen(); expect(screen.getByText('149.99 zł')).toBeOnTheScreen(); }); it('wywołuje onPress z id produktu po naciśnięciu', () => { const onPress = jest.fn(); render(); fireEvent.press( screen.getByRole('button', { name: /słuchawki bezprzewodowe/i }) ); expect(onPress).toHaveBeenCalledWith('prod-1'); expect(onPress).toHaveBeenCalledTimes(1); }); it('pokazuje komunikat o braku gdy produkt niedostępny', () => { const outOfStockProduct = { ...mockProduct, inStock: false }; render(); expect(screen.getByText('Brak w magazynie')).toBeOnTheScreen(); }); }); ``` Testy odpytują według treści tekstowej i ról dostępności zamiast test ID lub wewnętrznych szczegółów komponentu. To podejście wyłapuje regresje wpływające na użytkowników, pozostając odpornym na refaktoryzację. ## Monitorowanie Wydajności w Produkcji React Native 0.87 integruje się z [Sentry](https://docs.sentry.io/platforms/react-native/) i podobnymi narzędziami do monitorowania wydajności produkcyjnej. Kluczowe metryki do śledzenia: - **Time to Interactive (TTI)**: Jak długo do momentu gdy aplikacja reaguje na input użytkownika - **Spadki klatek**: Klatki renderowane dłużej niż 16.67ms - **Wykorzystanie wątku JavaScript**: Wysokie użycie wskazuje na kosztowne obliczenia blokujące UI - **Wzrost pamięci**: Stały wzrost sugeruje wycieki ```typescript // app/_layout.tsx import * as Sentry from '@sentry/react-native'; import { useEffect } from 'react'; import { AppState, AppStateStatus } from 'react-native'; Sentry.init({ dsn: process.env.EXPO_PUBLIC_SENTRY_DSN, tracesSampleRate: 0.2, profilesSampleRate: 0.1, enableAutoPerformanceTracing: true, }); export default function RootLayout() { useEffect(() => { const subscription = AppState.addEventListener( 'change', (state: AppStateStatus) => { if (state === 'active') { Sentry.addBreadcrumb({ category: 'app.lifecycle', message: 'Aplikacja stała się aktywna', level: 'info', }); } } ); return () => subscription.remove(); }, []); // ... reszta layoutu } ``` ## Kluczowe Wnioski dla Tworzenia Aplikacji React Native w 2026 - Nowa Architektura (JSI, Fabric, TurboModules) jest obowiązkowa w React Native 0.87. Stary bridge już nie istnieje. - JSI umożliwia synchroniczne wywołania natywne. Należy ich używać oszczędnie dla operacji poniżej 16ms. - Fabric renderuje UI w C++ i synchronizuje z JavaScript przez JSI. To eliminuje asynchroniczne wąskie gardło renderowania. - TurboModules ładują się leniwie i dostarczają type-safe wiązania generowane ze specyfikacji TypeScript. - [Expo Router](https://docs.expo.dev/router/introduction/) oferuje nawigację opartą na plikach podobną do Next.js App Router. - React Native Testing Library testuje komponenty przez ich publiczne API i drzewo dostępności. - Aplikacje produkcyjne powinny śledzić TTI, spadki klatek i wykorzystanie pamięci od pierwszego dnia. Dla głębszego spojrzenia na budowanie kompletnych aplikacji, zobacz [tutorial kompletnej aplikacji React Native](/blog/react-native/react-native-building-complete-mobile-app). [Przewodnik po Nowej Architekturze](/blog/react-native/react-native-new-architecture-hermes-v1-bridgeless) obejmuje migrację ze starszych wersji. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/pl/blog/react-native/react-native-app-development-2026-complete-guide