Przejdź do głównej zawartości

Wzorce Rozwoju React Native

Twój FlatList zacina się na średniej klasy Androidzie w momencie, gdy lista przekracza kilkaset wierszy, build produkcyjny crashuje na module natywnym, którego dev client Expo nigdy nie uruchomił, a ekran offline, który PM demonstrował w zeszłym tygodniu, po cichu gubi zapisy, gdy sieć się zrywa. Żaden z tych problemów nie powtarza się na symulatorze na twoim Macu z układem M. To właśnie przepaść między demem React Native a aplikacją gotową do wdrożenia - i dokładnie tu agent AI zarabia na swoje utrzymanie, bo poprawki są mechaniczne, specyficzne dla bibliotek i żmudne do napisania ręcznie.

Ten przepis przeprowadza przez produkcyjny workflow: szkielet na Expo (zalecana ścieżka dla nowych aplikacji), podłączenie nawigacji i stanu offline-first z aktualnymi bibliotekami, naprawa zacinającej się listy oraz wdrożenie przez CI do TestFlight i Play. Każdy krok napędza prompt, który możesz wkleić do Cursor, Claude Code lub Codex.

  • Wielokrotnego użytku prompt do szkieletu, który tworzy projekt Expo + TypeScript + React Navigation + Vitest/RNTL, identyczny we wszystkich trzech narzędziach
  • Prompt gotowy do skopiowania dla store’a offline-first opartego na react-native-mmkv + TanStack Query (lub WatermelonDB, gdy potrzebujesz prawdziwej synchronizacji)
  • Prompt, który zamienia zacinający się FlatList w ekran @shopify/flash-list v2 z poprawnym recyklingiem widoków i paginacją
  • Prompt na przepływ uwierzytelniania biometrycznego oparty na expo-local-authentication + expo-secure-store
  • Poradnik “Gdy To Się Zepsuje” dla trybów awarii, które nigdy nie pokazują się na symulatorze: cache Metro, Hermes vs JSC, interop Nowej Architektury i dryf buildów natywnych

npx react-native init i @react-native-community/cli init nie są już zalecanym punktem wyjścia - dokumentacja React Native kieruje teraz nowe aplikacje do frameworka, a Expo jest domyślnym wyborem. Podaj agentowi pełny stack z góry, aby dobrał kompatybilne wersje, zamiast zgadywać.

Otwórz tryb Agent (Cmd/Ctrl + I) i wklej poniższy prompt do szkieletu. Cursor uruchomi npx create-expo-app@latest w zintegrowanym terminalu, a następnie edytuje wygenerowane pliki. Użyj checkpointu przed akceptacją, aby móc cofnąć cały szkielet jednym kliknięciem, jeśli okablowanie nawigacji okaże się błędne.

Jeśli naprawdę potrzebujesz bare workflow (niestandardowy moduł natywny, którego nie obsługują config plugins), powiedz agentowi, aby zamiast tego użył npx @react-native-community/cli@latest init - ale pamiętaj, że nie jest to już domyślna ścieżka i bierzesz na siebie utrzymanie buildów natywnych.

Ekran, który demonstruje się idealnie, a potem gubi dane, to prawie zawsze warstwa stanu zakładająca, że sieć działa. Bądź konkretny co do silnika przechowywania danych i strategii synchronizacji - “dodaj obsługę offline” da ci mglisty wrapper na AsyncStorage; podanie nazwy react-native-mmkv i TanStack Query da ci coś, co przetrwa kapryśny tunel kolejowy.

Gdy model danych jest relacyjny i potrzebujesz prawdziwej dwukierunkowej synchronizacji (a nie tylko odtwarzania cache’u), skieruj agenta na WatermelonDB:

Krótki przykład tego, co agent powinien wyprodukować dla persistera MMKV - zachowaj ten rozmiar, to nośny element łączący, a nie tutorial:

import { MMKV } from 'react-native-mmkv';
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client';
const storage = new MMKV();
const persister = {
persistClient: (c) => storage.set('rq-cache', JSON.stringify(c)),
restoreClient: () => {
const v = storage.getString('rq-cache');
return v ? JSON.parse(v) : undefined;
},
removeClient: () => storage.delete('rq-cache'),
};

Oceń wynik na jednej osi, którą agent często myli: czy kolejka mutacji deduplikuje odtworzenia? Zapytaj “co się stanie, jeśli aplikacja zostanie zabita w trakcie synchronizacji i ponownie otwarta offline?” - jeśli odpowiedź jest mglista, kolejka nie jest jeszcze trwała.

FlatList jest w porządku, dopóki nie przestaje być. Pojedyncza zmiana wydajnościowa o największej dźwigni w większości aplikacji RN to podmiana gorącej listy na @shopify/flash-list, która recyklinguje widoki zamiast montować jeden na wiersz. Przypnij wersję v2 (@shopify/flash-list v2 to napisany od zera projekt działający wyłącznie na Nowej Architekturze) i całkowicie usuń propsy estimatedItemSize / estimatedListSize z v1 - v2 mierzy elementy synchronicznie i usunął je (“No Longer Needed!”). Nie pozwól agentowi zatrzymać się na podmianie drop-in; prawdziwy zysk daje stabilny recykling i poprawne getItemType dla mieszanych wierszy.

Pytanie ewaluacyjne tutaj: zapytaj agenta, jak wiersze są recyklingowane. Jeśli twoja lista miesza kształty wierszy (nagłówki, reklamy, różne typy kart) i nie ma getItemType, v2 zrecyklinguje wysoką kartę w niski slot i zobaczysz miganie lub błędne wysokości - to współczesny odpowiednik zacinania z błędnym estymatem z v1. Dla bardzo długich list sprawdź też, czy drawDistance jest dostrojony, a nie pozostawiony na zgadywankę.

Uwierzytelnianie to kolejne miejsce, w którym dema kłamią: Face ID działa w symulatorze przy włączonym przełączniku “Enrolled”, a potem prawdziwe urządzenie bez zarejestrowanej biometrii rzuca wyjątek. Wymień moduły Expo, aby agent obsłużył ścieżki braku rejestracji i awaryjne.

End-to-End: Od Pustego Repozytorium do Przetestowanej Funkcji

Dział zatytułowany „End-to-End: Od Pustego Repozytorium do Przetestowanej Funkcji”

Dla zadania naprawdę sekwencyjnego - budowy funkcji od zera - prowadź agenta przez uporządkowane kroki, a nie jeden megaprompt, abyś mógł skontrolować każdy artefakt, zanim kolejny się na nim oprze. Poniższy przepływ jest taki sam w Cursor, Claude Code i Codex; różni się tylko sposób wywołania (tryb Agent, claude "..." lub codex "...").

  1. Wygeneruj ekran i jego typy. “Create a ProjectList screen with a typed route in RootStackParamList, fetching projects via a useProjects() TanStack Query hook. Stub the hook to return mock data for now.” Oczekiwany wynik: ekran, wpis w param-list i typowany hook.

  2. Podłącz prawdziwe dane oraz stany pusty/błędu. “Replace the mock with a real fetch against /api/projects, add loading skeletons, an empty state, and an error state with a retry button that calls refetch().” Sprawdź, czy stan błędu faktycznie ujawnia awarie sieci, a nie tylko wyjątki.

  3. Przyspiesz listę. Wklej powyższy prompt FlashList przeciwko ProjectList. Zweryfikuj, że celuje w v2 bez propsów estymujących i że mieszane typy wierszy dostają getItemType.

  4. Przetestuj. “Write React Native Testing Library tests for ProjectList: it renders the loading state, renders rows on success, shows the empty state for [], and calls refetch when the retry button is pressed. Mock the query hook.” Uruchom zestaw testów i potwierdź, że asercja stanu pustego jest prawdziwa, a nie snapshotem.

Debugowanie w 2026: React Native DevTools, Nie Flipper

Dział zatytułowany „Debugowanie w 2026: React Native DevTools, Nie Flipper”

Jeśli artykuł każe ci skonfigurować Flippera, jest nieaktualny. Natywna integracja Flippera z React Native została wycofana w RN 0.73 i usunięta po tej wersji; Meta zarchiwizowała repozytorium Flippera pod koniec 2025 roku. Domyślnym debuggerem są teraz React Native DevTools - naciśnij j w terminalu Metro (lub potrząśnij urządzeniem i wybierz “Open DevTools”), aby uruchomić interfejs Chrome DevTools oparty na Hermes, bez żadnego kroku instalacji. Dla bogatszej inspekcji sieci/stanu typowym dodatkiem jest Reactotron.

Buildy i uploady do sklepów to najbardziej mechaniczna część całego pipeline’u, co czyni je idealnym kandydatem do oddelegowania. Na Expo to EAS Build odpowiada za natywną kompilację i wysyłkę; na bare RN sam podłączasz Fastlane do GitHub Actions.

W trybie Agent: “Add an EAS Build + EAS Submit setup for this Expo app and a GitHub Actions workflow that builds iOS and Android on tags and submits to TestFlight and Play internal testing.” Cursor utworzy szkielet eas.json, workflow i wyjaśni, które sekrety dodać.

To są tryby awarii, które nigdy nie pojawiają się na twoim symulatorze - oraz kroki naprawcze do przekazania agentowi.