Communitygithub.com

react-native-patterns

React Native- und Expo-App-Muster – Expo Router Navigation, Zustandstrennung (Server/Client/Route/Form), TanStack Query Datenabruf mit Zod, performante Listen, NativeWind/StyleSheet Styling, native APIs und sicherer Speicher. Verwende dies beim Erstellen oder Bearbeiten von React Native/Expo Screens, Komponenten, Navigation oder Datenebenen.

Was ist react-native-patterns?

Diese Skill-Datei enthält praktische Muster für die Entwicklung produktionsreifer React Native-Apps mit Expo. Sie behandelt Navigation, Zustandsverwaltung, Datenabruf, Listen, Styling und native APIs und ist darauf ausgelegt, mit dem `rules/react-native/`-Regelset zusammenzuarbeiten, das festlegt, *was* zu erzwingen ist – dieser Skill zeigt, *wie* es geht. Die beschriebenen Bibliotheken (NativeWind, Zustand/Jotai, TanStack Query) sind gängige Beispiele; die dahinterstehenden Muster sind wichtiger als das spezifische Paket. Zod wird für die Validierung verwendet, um mit den bestehenden `typescript/`-Regeln konsistent zu bleiben. Die Muster setzen den verwalteten Expo-Workflow (Expo Router, EAS, `expo-*`-Module) auf der New Architecture voraus und decken keine Web-/React-DOM-Szenarien ab. Der Skill ist nützlich, wenn du React Native/Expo Screens oder Komponenten erstellst, Routing mit Expo Router einrichtest, entscheidest, wo Zustand hingehört (Server-Cache vs. Client-Store vs. Routen-Parameter vs. Formular), Datenabruf mit TanStack Query und Zod aufsetzt, lange Listen renderst, einen Styling-Ansatz wählst oder native APIs und sicheren Speicher nutzt.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/react-native-patterns

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

React Native / Expo Patterns (Muster für React Native / Expo)

Praktische Muster für die Entwicklung produktionsreifer React Native-Apps mit Expo. Behandelt Navigation, Zustand, Datenabruf, Listen, Styling und native APIs. Arbeitet mit dem rules/react-native/-Regelset zusammen: Regeln legen fest, was zu erzwingen ist – dieser Skill zeigt, wie.

Die unten genannten Bibliotheken (NativeWind, Zustand/Jotai, TanStack Query) sind gängige, etablierte Optionen, die zur Veranschaulichung gezeigt werden – die Muster sind wichtiger als das spezifische Paket, und jedes Äquivalent funktioniert. Zod wird zur Validierung verwendet, um mit den bestehenden typescript/-Regeln von ECC konsistent zu bleiben.

Diese Muster setzen den verwalteten Expo-Workflow (Expo Router, EAS, expo-*-Module) auf der New Architecture voraus (der Standard in aktuellen Expo SDKs, ab SDK 55+ Pflicht). Sie setzen NICHT das Browser-DOM voraus – React Native hat kein <div>, keine URL-Leiste und keine Standard-Datenabruf-Methoden des Webs.

Wann aktivieren

Verwende diesen Skill bei:

  • Erstellen oder Bearbeiten von React Native / Expo Screens, Komponenten oder Navigation
  • Einrichten des Routings mit Expo Router (dateibasiertes app/-Verzeichnis)
  • Entscheiden, wo der Zustand hingehört (Server-Cache vs. Client-Store vs. Routen-Parameter vs. Formular)
  • Aufsetzen des Datenabrufs mit TanStack Query und Validieren der Antworten mit Zod
  • Rendern langer oder schwerer Listen
  • Auswählen oder Anwenden eines Styling-Ansatzes (NativeWind oder StyleSheet)
  • Zugreifen auf native Geräte-APIs (Kamera, Standort, Benachrichtigungen) oder sicheren Speicher
  • Überprüfen von RN-Code auf mobile-spezifische Probleme

Verwende NICHT die Web/React-DOM-Muster hier – URL-als-Zustand, <div> und SWR-für-Browser sind auf React Native nicht anwendbar.

Kernkonzepte

Projektstruktur (Expo Router)

Dateibasiertes Routing unter app/. Halte Routen-Dateien schlank: Sie lesen und validieren Parameter und delegieren dann an eine Screen-Komponente, die in components/ oder features/ lebt.

app/
  _layout.tsx          # Root-Stack
  (tabs)/
    _layout.tsx        # Tab-Navigator
    index.tsx          # Startseite
  user/[id].tsx        # dynamische Route
components/
features/
  user/UserProfile.tsx

Navigation: Routen-Parameter validieren

Deep Links und dynamische Routen liefern ungeprüfte Zeichenketten. Validiere sie vor der Verwendung mit Zod.

// app/user/[id].tsx
import { useLocalSearchParams, router } from 'expo-router'
import { z } from 'zod'
import { UserProfile } from '@/features/user/UserProfile'

const Params = z.object({ id: z.string().uuid() })

export default function UserRoute() {
  const parsed = Params.safeParse(useLocalSearchParams())
  if (!parsed.success) {
    router.replace('/not-found')
    return null
  }
  return <UserProfile userId={parsed.data.id} />
}

Zustand: Belange getrennt halten

Dupliziere keine Serverdaten in einen Client-Store. Jeder Belang hat sein eigenes Zuhause.

BelangÜbliche Wahlmöglichkeiten
Server-Zustand (Remote-Daten)eine Server-Cache-Bibliothek (TanStack Query, SWR)
Client/UI-Zustandein leichtgewichtiger Store (Zustand, Jotai) oder Context
Routen-/NavigationszustandExpo Router Parameter
Formularzustandeine Formularbibliothek (z. B. React Hook Form) + Schema-Validierung
Geheimnisse / Tokensexpo-secure-store
Nicht-geheime PersistenzAsyncStorage / MMKV

Bevorzuge lokales useState, bis ein Zustand wirklich geteilt werden muss.

Datenabruf: eine Cache-Bibliothek + Zod

Verwende eine Server-Cache-Bibliothek (TanStack Query, SWR) anstelle von fetch in useEffect. Validiere an der Grenze und leite Typen aus dem Schema ab. Behandle Lade-, Fehler- und Leerzustände explizit. (Beispiel verwendet TanStack Query.)

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { z } from 'zod'

const User = z.object({ id: z.string(), email: z.string().email() })
type User = z.infer<typeof User>

export function useUser(id: string) {
  return useQuery({
    queryKey: ['user', id],
    queryFn: async (): Promise<User> => User.parse(await api.getUser(id)),
  })
}

export function useUpdateEmail(id: string) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (email: string) => api.updateEmail(id, email),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['user', id] }),
  })
}

Listen: virtualisieren, niemals ein großes Array in einer ScrollView abbilden

import { FlatList } from 'react-native'

<FlatList
  data={items}
  keyExtractor={(item) => item.id}
  renderItem={renderItem}          // memoisiert
  initialNumToRender={10}
  windowSize={5}
/>

Verwende FlashList (Shopify) für große oder heterogene Listen.

Styling: ein System auswählen

StyleSheet.create() ist die framework-native Option; Utility-Class-Bibliotheken (z. B. NativeWind) sind eine übliche Alternative. Wähle eins und bleibe konsistent. Erstelle niemals Style-Objekte inline in JSX auf heißen Pfaden.

// NativeWind
<View className="p-4 rounded-2xl bg-white">
  <Text className="text-base font-semibold">Hallo</Text>
</View>

// StyleSheet
const styles = StyleSheet.create({ card: { padding: 16, borderRadius: 16, backgroundColor: '#fff' } })
<View style={styles.card}>...</View>

Native APIs: in Hooks kapseln, Effekte bereinigen

Halte Expo SDK-Aufrufe und Abonnements innerhalb von use*-Hooks, nicht in JSX. Bereinige immer.

import { useEffect, useState } from 'react'
import * as Location from 'expo-location'

type LocationState =
  | { status: 'loading' }
  | { status: 'denied' }
  | { status: 'granted'; coords: Location.LocationObjectCoords }

export function useCurrentLocation() {
  // Verfolge den Status, nicht nur die Koordinaten – damit die UI
  // „wird noch geladen“ von „Berechtigung verweigert“ unterscheiden und
  // eine hilfreiche Nachricht anzeigen kann.
  const [state, setState] = useState<LocationState>({ status: 'loading' })

  useEffect(() => {
    let active = true
    ;(async () => {
      const { status } = await Location.requestForegroundPermissionsAsync()
      if (status !== 'granted') {
        if (active) setState({ status: 'denied' })
        return
      }
      const pos = await Location.getCurrentPositionAsync({})
      if (active) setState({ status: 'granted', coords: pos.coords })
    })()
    return () => { active = false }   // veraltetes Ergebnis nach Unmount ignorieren
  }, [])

  return state
}

Sicherer Speicher für Tokens

import * as SecureStore from 'expo-secure-store'

await SecureStore.setItemAsync('auth_token', token)   // Keychain / Keystore
const token = await SecureStore.getItemAsync('auth_token')

Codebeispiele

Ein vollständiger Screen: Route → Abfrage → Liste → Zustände

// app/(tabs)/orders.tsx
import { memo, useCallback } from 'react'
import { FlatList, Text, View } from 'react-native'
import { useQuery } from '@tanstack/react-query'
import { z } from 'zod'

const OrderSchema = z.object({ id: z.string(), total: z.number(), status: z.string() })
const OrdersSchema = z.array(OrderSchema)
type Order = z.infer<typeof OrderSchema>

function useOrders() {
  return useQuery({
    queryKey: ['orders'],
    queryFn: async () => OrdersSchema.parse(await api.listOrders()),
  })
}

// Memoisiert, damit die Referenz über Rendervorgänge hinweg stabil bleibt (siehe Listen-Hinweise).
const OrderRow = memo(function OrderRow({ item }: { item: Order }) {
  return (
    <View className="px-4 py-3 border-b border-neutral-200">
      <Text className="font-medium">#{item.id}</Text>
      <Text className="text-neutral-500">{item.status} · ${item.total}</Text>
    </View>
  )
})

export default function OrdersScreen() {
  const { data, isLoading, isError, refetch, isRefetching } = useOrders()
  const renderItem = useCallback(({ item }: { item: Order }) => <OrderRow item={item} />, [])

  if (isLoading) return <Centered><Text>Lädt…</Text></Centered>
  if (isError) return <Centered><Text accessibilityRole="alert">Bestellungen konnten nicht geladen werden.</Text></Centered>
  if (!data?.length) return <Centered><Text>Noch keine Bestellungen.</Text></Centered>

  return (
    <FlatList
      data={data}
      keyExtractor={(o) => o.id}
      onRefresh={refetch}
      refreshing={isRefetching}
      renderItem={renderItem}
    />
  )
}

Ein Formular: React Hook Form + Zod-Resolver

import { useForm, Controller } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
import { TextInput, Button, Text } from 'react-native'

const Schema = z.object({ email: z.string().email('Ungültige E-Mail') })
type FormValues = z.infer<typeof Schema>

export function EmailForm({ onSubmit }: { onSubmit: (v: FormValues) => void }) {
  const { control, handleSubmit, formState: { errors } } = useForm<FormValues>({
    resolver: zodResolver(Schema),
    defaultValues: { email: '' },
  })

  return (
    <>
      <Controller
        control={control}
        name="email"
        render={({ field: { value, onChange, onBlur } }) => (
          <TextInput
            value={value}
            onChangeText={onChange}
            onBlur={onBlur}
            autoCapitalize="none"
            keyboardType="email-address"
            accessibilityLabel="E-Mail-Adresse"
          />
        )}
      />
      {errors.email && <Text accessibilityRole="alert">{errors.email.message}</Text>}
      <Button title="Speichern" onPress={handleSubmit(onSubmit)} />
    </>
  )
}

Anti-Patterns (Anti-Muster)

// FALSCH: Großes Array innerhalb einer ScrollView abgebildet (keine Virtualisierung, ruckelig, hoher Speicher)
<ScrollView>{items.map((i) => <Row key={i.id} item={i} />)}</ScrollView>
// RICHTIG: FlatList / FlashList

// FALSCH: Serverdaten in einen Client-Store kopiert (zwei Wahrheitsquellen, veraltete Daten)
const useStore = create((set) => ({ users: [], setUsers: (u) => set({ users: u }) }))
useEffect(() => { getUsers().then(setUsers) }, [])
// RICHTIG: useQuery besitzt den Server-Zustand; leite ab, was du benötigst

// FALSCH: Tokens in AsyncStorage (nicht verschlüsselt)
await AsyncStorage.setItem('auth_token', token)
// RICHTIG: expo-secure-store

// FALSCH: Deep-Link-Parametern vertrauen
const { id } = useLocalSearchParams(); fetchUser(id)
// RICHTIG: Vor Verwendung mit Zod validieren

// FALSCH: Inline-Style-Objekt wird bei jedem Rendern auf einem heißen Pfad neu erstellt
<View style={{ padding: 16, backgroundColor: '#fff' }} />
// RICHTIG: StyleSheet.create auf Modulebene oder NativeWind className

// FALSCH: Echtes Geheimnis im Bundle ausgeliefert
const STRIPE_SECRET = 'sk_live_...'
// RICHTIG: Privilegierte Aufrufe serverseitig halten; nur öffentliche Schlüssel ausliefern, die durch Backend-Regeln geschützt sind

Best Practices (Bewährte Vorgehensweisen)

  • Halte Routen-Dateien schlank; lege Logik in Screen-Komponenten und use*-Hooks.
  • Validiere jede externe Eingabe (API-Antworten, Routen-Parameter, Push-Payloads) mit Zod.
  • Lasse TanStack Query den Server-Zustand besitzen; halte Client-Stores klein.
  • Rendere immer Lade-, Fehler- und Leerzustände – niemals nur einen Spinner ohne Fallback.
  • Virtualisiere Listen; memoisiere renderItem; sorge für einen stabilen keyExtractor.
  • Verwende react-native-reanimated für Animationen (UI-Thread); vermeide schwere Arbeit auf dem JS-Thread.
  • Speichere Tokens in expo-secure-store; vertraue dem Client niemals für die Autorisierung.
  • Respektiere von Anfang an Safe Areas, Dynamic Type und Accessibilitäts-Rollen/-Labels.
  • Bestätige vor der Veröffentlichung die Kompatibilität mit der New Architecture für jede native Abhängigkeit.

Verwandte Skills

  • frontend-patterns – React/Next.js (Web)-Muster; nützlich für gemeinsame React-Konzepte, aber DOM-spezifisch.
  • coding-standards – TypeScript/JavaScript-Idiome, die für RN-Code gelten.
  • tdd-workflow, e2e-testing – Testprozess (verwende Jest + React Native Testing Library, Maestro/Detox für RN).
  • security-review – Allgemeine Sicherheits-Checkliste, die die RN-Bundle-/Geheimnis-Hinweise oben ergänzt.

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

Verwandte Skills