Zum Inhalt

React Native Cheatsheet

React Native - Lernen Sie einmalig, Schreiben Sie Anywhere

React Native ist ein Rahmen für den Aufbau nativer mobiler Anwendungen mit React. Es ermöglicht Entwicklern, React zusammen mit nativen Plattform-Funktionen zu verwenden, um mobile Apps für iOS und Android mit einer einzigen Codebase zu erstellen. < p>

generieren

Inhaltsverzeichnis

  • [Installation](LINK_0 -%20(LINK_0)
  • Core Components
  • [Navigation](_LINK_0 -%20[State%20Management](_LINK_0 -%20(Styling)(_LINK_0__)
  • APIs und Services
  • Native Module
  • [Performance](LINK_0 -%20Test
  • [Debugging](_LINK_0__ -%20[Bestellung](_LINK_0 -%20[Platform-Specific%20Code](_LINK_0 -%20[Drittparteienbibliotheken](LINK_0 -%20Beste%20Praktiken
  • (__LINK_0___)

Installation

Entwicklung Umwelt Setup

Voraussetzungen

# Install Node.js (LTS version recommended)
# Download from https://nodejs.org/

# Install Watchman (macOS)
brew install watchman

# Install Java Development Kit (JDK 11)
# Download from https://adoptopenjdk.net/

# Install Android Studio
# Download from https://developer.android.com/studio

# Install Xcode (macOS only)
# Download from Mac App Store
```_

#### React Native CLI
```bash
# Install React Native CLI globally
npm install -g react-native-cli

# Alternative: Use npx (recommended)
npx react-native --version

# Install Expo CLI (for Expo workflow)
npm install -g expo-cli
```_

#### Android Development Setup
```bash
# Set environment variables (add to ~/.bashrc or ~/.zshrc)
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/tools/bin
export PATH=$PATH:$ANDROID_HOME/platform-tools

# Create Android Virtual Device (AVD)
# Open Android Studio > AVD Manager > Create Virtual Device

# Start Android emulator
emulator -avd Pixel_4_API_30
```_

#### iOS Development Setup (nur macOS)
```bash
# Install CocoaPods
sudo gem install cocoapods

# Install iOS Simulator
# Included with Xcode

# Install iOS dependencies
cd ios && pod install && cd ..
```_

### Projekterstellung

#### React Native CLI
```bash
# Create new project
npx react-native init MyApp

# Create project with specific template
npx react-native init MyApp --template react-native-template-typescript

# Navigate to project
cd MyApp

# Install dependencies
npm install

# Install iOS dependencies (macOS only)
cd ios && pod install && cd ..
```_

#### Risikopositionen
```bash
# Create new Expo project
expo init MyExpoApp

# Choose template
# - blank: minimal app
# - blank (TypeScript): minimal TypeScript app
# - tabs: app with tab navigation
# - minimal: bare minimum setup

# Navigate to project
cd MyExpoApp

# Start development server
expo start
```_

### Ausführen der App

#### React Native CLI
```bash
# Run on Android
npx react-native run-android

# Run on iOS (macOS only)
npx react-native run-ios

# Run on specific device
npx react-native run-ios --device "iPhone 12"

# Run on specific simulator
npx react-native run-ios --simulator="iPhone 12 Pro Max"

# Start Metro bundler separately
npx react-native start

# Reset cache
npx react-native start --reset-cache
```_

#### Exposition
```bash
# Start development server
expo start

# Run on Android device/emulator
expo start --android

# Run on iOS device/simulator
expo start --ios

# Run in web browser
expo start --web

# Run in tunnel mode (for physical devices)
expo start --tunnel
```_

## Erste Schritte

### Grundlegende App Struktur
```javascript
// App.js
import React from 'react';
import {
  SafeAreaView,
  ScrollView,
  StatusBar,
  StyleSheet,
  Text,
  View,
} from 'react-native';

const App = () => {
  return (
    <SafeAreaView style={styles.container}>
      <StatusBar barStyle="dark-content" />
      <ScrollView contentInsetAdjustmentBehavior="automatic">
        <View style={styles.body}>
          <Text style={styles.title}>Welcome to React Native!</Text>
          <Text style={styles.subtitle}>
            Edit App.js to change this screen and then come back to see your edits.
          </Text>
        </View>
      </ScrollView>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
  body: {
    padding: 20,
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    textAlign: 'center',
    marginBottom: 20,
  },
  subtitle: {
    fontSize: 16,
    textAlign: 'center',
    color: '#666',
  },
});

export default App;
```_

### TypScript Setup
```bash
# Add TypeScript to existing project
npm install --save-dev typescript @types/react @types/react-native

# Create tsconfig.json
npx tsc --init

# Rename App.js to App.tsx
mv App.js App.tsx
```_

```json
// tsconfig.json
{
  "compilerOptions": {
    "target": "es2017",
    "lib": ["es2017", "es7", "es6"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-native"
  },
  "include": [
    "src/**/*",
    "App.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}
```_

### Projektstruktur

MyApp/ ├── android/ # Android-specific code ├── ios/ # iOS-specific code ├── src/ # Source code │ ├── components/ # Reusable components │ ├── screens/ # Screen components │ ├── navigation/ # Navigation configuration │ ├── services/ # API services │ ├── utils/ # Utility functions │ ├── hooks/ # Custom hooks │ ├── context/ # React context │ └── types/ # TypeScript types ├── tests/ # Test files ├── App.js # Main app component ├── index.js # App entry point ├── package.json # Dependencies └── metro.config.js # Metro bundler config


## Kernkomponenten

### Grundkomponenten
```javascript
import React, { useState } from 'react';
import {
  View,
  Text,
  TextInput,
  TouchableOpacity,
  Image,
  ScrollView,
  FlatList,
  Alert,
} from 'react-native';

const BasicComponents = () => {
  const [text, setText] = useState('');
  const [items] = useState([
    { id: '1', title: 'Item 1' },
    { id: '2', title: 'Item 2' },
    { id: '3', title: 'Item 3' },
  ]);

  const handlePress = () => {
    Alert.alert('Button Pressed', `You entered: ${text}`);
  };

  const renderItem = ({ item }) => (
    <View style={styles.listItem}>
      <Text>{item.title}</Text>
    </View>
  );

  return (
    <ScrollView style={styles.container}>
      {/* Text Component */}
      <Text style={styles.heading}>React Native Components</Text>

      {/* TextInput Component */}
      <TextInput
        style={styles.input}
        placeholder="Enter text here"
        value={text}
        onChangeText={setText}
        multiline={false}
        autoCapitalize="none"
        autoCorrect={false}
      />

      {/* TouchableOpacity Component */}
      <TouchableOpacity style={styles.button} onPress={handlePress}>
        <Text style={styles.buttonText}>Press Me</Text>
      </TouchableOpacity>

      {/* Image Component */}
      <Image
        source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }}
        style={styles.image}
        resizeMode="contain"
      />

      {/* Local Image */}
      <Image
        source={require('./assets/logo.png')}
        style={styles.image}
      />

      {/* FlatList Component */}
      <FlatList
        data={items}
        renderItem={renderItem}
        keyExtractor={item => item.id}
        style={styles.list}
      />
    </ScrollView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
  },
  heading: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 20,
  },
  input: {
    borderWidth: 1,
    borderColor: '#ddd',
    padding: 10,
    marginBottom: 20,
    borderRadius: 5,
  },
  button: {
    backgroundColor: '#007AFF',
    padding: 15,
    borderRadius: 5,
    alignItems: 'center',
    marginBottom: 20,
  },
  buttonText: {
    color: 'white',
    fontWeight: 'bold',
  },
  image: {
    width: 100,
    height: 100,
    marginBottom: 20,
  },
  list: {
    maxHeight: 200,
  },
  listItem: {
    padding: 10,
    borderBottomWidth: 1,
    borderBottomColor: '#eee',
  },
});
```_

### Erweiterte Komponenten
```javascript
import React, { useState, useRef } from 'react';
import {
  View,
  Text,
  Modal,
  Switch,
  Slider,
  Picker,
  ActivityIndicator,
  RefreshControl,
  Animated,
  PanGestureHandler,
} from 'react-native';

const AdvancedComponents = () => {
  const [modalVisible, setModalVisible] = useState(false);
  const [switchValue, setSwitchValue] = useState(false);
  const [sliderValue, setSliderValue] = useState(50);
  const [pickerValue, setPickerValue] = useState('option1');
  const [refreshing, setRefreshing] = useState(false);
  const animatedValue = useRef(new Animated.Value(0)).current;

  const onRefresh = () => {
    setRefreshing(true);
    setTimeout(() => setRefreshing(false), 2000);
  };

  const startAnimation = () => {
    Animated.timing(animatedValue, {
      toValue: 1,
      duration: 1000,
      useNativeDriver: true,
    }).start();
  };

  return (
    <ScrollView
      style={styles.container}
      refreshControl={
        <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
      }
    >
      {/* Modal Component */}
      <TouchableOpacity
        style={styles.button}
        onPress={() => setModalVisible(true)}
      >
        <Text style={styles.buttonText}>Show Modal</Text>
      </TouchableOpacity>

      <Modal
        animationType="slide"
        transparent={true}
        visible={modalVisible}
        onRequestClose={() => setModalVisible(false)}
      >
        <View style={styles.modalContainer}>
          <View style={styles.modalContent}>
            <Text style={styles.modalText}>This is a modal!</Text>
            <TouchableOpacity
              style={styles.closeButton}
              onPress={() => setModalVisible(false)}
            >
              <Text style={styles.buttonText}>Close</Text>
            </TouchableOpacity>
          </View>
        </View>
      </Modal>

      {/* Switch Component */}
      <View style={styles.row}>
        <Text>Enable notifications:</Text>
        <Switch
          value={switchValue}
          onValueChange={setSwitchValue}
          trackColor={{ false: '#767577', true: '#81b0ff' }}
          thumbColor={switchValue ? '#f5dd4b' : '#f4f3f4'}
        />
      </View>

      {/* Slider Component */}
      <View style={styles.sliderContainer}>
        <Text>Value: {Math.round(sliderValue)}</Text>
        <Slider
          style={styles.slider}
          minimumValue={0}
          maximumValue={100}
          value={sliderValue}
          onValueChange={setSliderValue}
          minimumTrackTintColor="#1fb28a"
          maximumTrackTintColor="#d3d3d3"
          thumbStyle={{ backgroundColor: '#1fb28a' }}
        />
      </View>

      {/* Picker Component */}
      <View style={styles.pickerContainer}>
        <Text>Select an option:</Text>
        <Picker
          selectedValue={pickerValue}
          style={styles.picker}
          onValueChange={setPickerValue}
        >
          <Picker.Item label="Option 1" value="option1" />
          <Picker.Item label="Option 2" value="option2" />
          <Picker.Item label="Option 3" value="option3" />
        </Picker>
      </View>

      {/* Activity Indicator */}
      <View style={styles.loadingContainer}>
        <ActivityIndicator size="large" color="#0000ff" />
        <Text>Loading...</Text>
      </View>

      {/* Animated Component */}
      <TouchableOpacity style={styles.button} onPress={startAnimation}>
        <Text style={styles.buttonText}>Start Animation</Text>
      </TouchableOpacity>

      <Animated.View
        style={[
          styles.animatedBox,
          {
            opacity: animatedValue,
            transform: [
              {
                translateY: animatedValue.interpolate({
                  inputRange: [0, 1],
                  outputRange: [0, 100],
                }),
              },
            ],
          },
        ]}
      >
        <Text>Animated Box</Text>
      </Animated.View>
    </ScrollView>
  );
};
```_

### Benutzerdefinierte Komponenten
```javascript
// components/CustomButton.js
import React from 'react';
import { TouchableOpacity, Text, StyleSheet } from 'react-native';

const CustomButton = ({ 
  title, 
  onPress, 
  style, 
  textStyle, 
  disabled = false,
  variant = 'primary' 
}) => {
  const buttonStyle = [
    styles.button,
    styles[variant],
    disabled && styles.disabled,
    style,
  ];

  const buttonTextStyle = [
    styles.buttonText,
    styles[`${variant}Text`],
    disabled && styles.disabledText,
    textStyle,
  ];

  return (
    <TouchableOpacity
      style={buttonStyle}
      onPress={onPress}
      disabled={disabled}
      activeOpacity={0.7}
    >
      <Text style={buttonTextStyle}>{title}</Text>
    </TouchableOpacity>
  );
};

const styles = StyleSheet.create({
  button: {
    paddingVertical: 12,
    paddingHorizontal: 24,
    borderRadius: 8,
    alignItems: 'center',
    justifyContent: 'center',
    minHeight: 44,
  },
  buttonText: {
    fontSize: 16,
    fontWeight: '600',
  },
  primary: {
    backgroundColor: '#007AFF',
  },
  primaryText: {
    color: '#FFFFFF',
  },
  secondary: {
    backgroundColor: '#F2F2F7',
    borderWidth: 1,
    borderColor: '#C7C7CC',
  },
  secondaryText: {
    color: '#007AFF',
  },
  danger: {
    backgroundColor: '#FF3B30',
  },
  dangerText: {
    color: '#FFFFFF',
  },
  disabled: {
    backgroundColor: '#C7C7CC',
  },
  disabledText: {
    color: '#8E8E93',
  },
});

export default CustomButton;

// Usage
import CustomButton from './components/CustomButton';

const App = () => {
  return (
    <View style={styles.container}>
      <CustomButton
        title="Primary Button"
        onPress={() => console.log('Primary pressed')}
        variant="primary"
      />

      <CustomButton
        title="Secondary Button"
        onPress={() => console.log('Secondary pressed')}
        variant="secondary"
        style={{ marginTop: 10 }}
      />

      <CustomButton
        title="Disabled Button"
        onPress={() => console.log('This won\'t fire')}
        disabled={true}
        style={{ marginTop: 10 }}
      />
    </View>
  );
};
```_

## Navigation

### React Navigation Setup
```bash
# Install React Navigation
npm install @react-navigation/native

# Install dependencies
npm install react-native-screens react-native-safe-area-context

# For iOS, install pods
cd ios && pod install && cd ..

# Install navigators
npm install @react-navigation/stack
npm install @react-navigation/bottom-tabs
npm install @react-navigation/drawer
npm install @react-navigation/material-top-tabs

# Install gesture handler (for stack navigator)
npm install react-native-gesture-handler

# For Android, add to MainActivity.java
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
```_

### Web-Screen-Navigation
```javascript
// navigation/AppNavigator.js
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

import HomeScreen from '../screens/HomeScreen';
import DetailsScreen from '../screens/DetailsScreen';
import ProfileScreen from '../screens/ProfileScreen';

const Stack = createStackNavigator();

const AppNavigator = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator
        initialRouteName="Home"
        screenOptions={{
          headerStyle: {
            backgroundColor: '#007AFF',
          },
          headerTintColor: '#fff',
          headerTitleStyle: {
            fontWeight: 'bold',
          },
        }}
      >
        <Stack.Screen 
          name="Home" 
          component={HomeScreen}
          options={{ title: 'My Home' }}
        />
        <Stack.Screen 
          name="Details" 
          component={DetailsScreen}
          options={({ route }) => ({ title: route.params.title })}
        />
        <Stack.Screen 
          name="Profile" 
          component={ProfileScreen}
          options={{
            headerRight: () => (
              <Button
                onPress={() => alert('This is a button!')}
                title="Info"
                color="#fff"
              />
            ),
          }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default AppNavigator;
```_

### Tab Navigator
```javascript
// navigation/TabNavigator.js
import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Ionicons } from '@expo/vector-icons';

import HomeScreen from '../screens/HomeScreen';
import SearchScreen from '../screens/SearchScreen';
import ProfileScreen from '../screens/ProfileScreen';

const Tab = createBottomTabNavigator();

const TabNavigator = () => {
  return (
    <Tab.Navigator
      screenOptions={({ route }) => ({
        tabBarIcon: ({ focused, color, size }) => {
          let iconName;

          if (route.name === 'Home') {
            iconName = focused ? 'home' : 'home-outline';
          } else if (route.name === 'Search') {
            iconName = focused ? 'search' : 'search-outline';
          } else if (route.name === 'Profile') {
            iconName = focused ? 'person' : 'person-outline';
          }

          return <Ionicons name={iconName} size={size} color={color} />;
        },
        tabBarActiveTintColor: '#007AFF',
        tabBarInactiveTintColor: 'gray',
      })}
    >
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Search" component={SearchScreen} />
      <Tab.Screen name="Profile" component={ProfileScreen} />
    </Tab.Navigator>
  );
};

export default TabNavigator;
```_

### Navigation Haken
```javascript
// screens/HomeScreen.js
import React from 'react';
import { View, Text, Button } from 'react-native';
import { useNavigation, useRoute, useFocusEffect } from '@react-navigation/native';

const HomeScreen = () => {
  const navigation = useNavigation();
  const route = useRoute();

  // Execute code when screen comes into focus
  useFocusEffect(
    React.useCallback(() => {
      console.log('Screen is focused');

      return () => {
        console.log('Screen is unfocused');
      };
    }, [])
  );

  const navigateToDetails = () => {
    navigation.navigate('Details', {
      itemId: 86,
      title: 'Details Screen',
      otherParam: 'anything you want here',
    });
  };

  const goBack = () => {
    navigation.goBack();
  };

  const resetNavigation = () => {
    navigation.reset({
      index: 0,
      routes: [{ name: 'Home' }],
    });
  };

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button title="Go to Details" onPress={navigateToDetails} />
      <Button title="Go Back" onPress={goBack} />
      <Button title="Reset Navigation" onPress={resetNavigation} />
    </View>
  );
};

export default HomeScreen;

// screens/DetailsScreen.js
import React from 'react';
import { View, Text, Button } from 'react-native';

const DetailsScreen = ({ route, navigation }) => {
  const { itemId, title, otherParam } = route.params;

  React.useEffect(() => {
    // Update header title
    navigation.setOptions({ title: title });
  }, [navigation, title]);

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
      <Text>Item ID: {itemId}</Text>
      <Text>Other Param: {otherParam}</Text>
      <Button
        title="Update Title"
        onPress={() => navigation.setOptions({ title: 'Updated!' })}
      />
      <Button
        title="Go to Details... again"
        onPress={() =>
          navigation.push('Details', {
            itemId: Math.floor(Math.random() * 100),
            title: 'New Details',
          })
        }
      />
      <Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
      <Button title="Go back" onPress={() => navigation.goBack()} />
    </View>
  );
};

export default DetailsScreen;
```_

### Drawer Navigator
```javascript
// navigation/DrawerNavigator.js
import React from 'react';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { View, Text, StyleSheet } from 'react-native';

import HomeScreen from '../screens/HomeScreen';
import ProfileScreen from '../screens/ProfileScreen';
import SettingsScreen from '../screens/SettingsScreen';

const Drawer = createDrawerNavigator();

// Custom drawer content
const CustomDrawerContent = (props) => {
  return (
    <View style={styles.drawerContainer}>
      <View style={styles.drawerHeader}>
        <Text style={styles.drawerHeaderText}>My App</Text>
      </View>
      <DrawerContentScrollView {...props}>
        <DrawerItemList {...props} />
      </DrawerContentScrollView>
    </View>
  );
};

const DrawerNavigator = () => {
  return (
    <Drawer.Navigator
      drawerContent={(props) => <CustomDrawerContent {...props} />}
      screenOptions={{
        drawerStyle: {
          backgroundColor: '#f6f6f6',
          width: 240,
        },
        drawerActiveTintColor: '#007AFF',
        drawerInactiveTintColor: '#666',
      }}
    >
      <Drawer.Screen 
        name="Home" 
        component={HomeScreen}
        options={{
          drawerIcon: ({ color }) => (
            <Ionicons name="home-outline" size={22} color={color} />
          ),
        }}
      />
      <Drawer.Screen 
        name="Profile" 
        component={ProfileScreen}
        options={{
          drawerIcon: ({ color }) => (
            <Ionicons name="person-outline" size={22} color={color} />
          ),
        }}
      />
      <Drawer.Screen 
        name="Settings" 
        component={SettingsScreen}
        options={{
          drawerIcon: ({ color }) => (
            <Ionicons name="settings-outline" size={22} color={color} />
          ),
        }}
      />
    </Drawer.Navigator>
  );
};

const styles = StyleSheet.create({
  drawerContainer: {
    flex: 1,
  },
  drawerHeader: {
    height: 100,
    backgroundColor: '#007AFF',
    justifyContent: 'center',
    alignItems: 'center',
  },
  drawerHeaderText: {
    color: 'white',
    fontSize: 18,
    fontWeight: 'bold',
  },
});

export default DrawerNavigator;
```_

## Staatliche Verwaltung

### React Hooks
```javascript
// hooks/useCounter.js
import { useState, useCallback } from 'react';

const useCounter = (initialValue = 0) => {
  const [count, setCount] = useState(initialValue);

  const increment = useCallback(() => {
    setCount(prev => prev + 1);
  }, []);

  const decrement = useCallback(() => {
    setCount(prev => prev - 1);
  }, []);

  const reset = useCallback(() => {
    setCount(initialValue);
  }, [initialValue]);

  return { count, increment, decrement, reset };
};

export default useCounter;

// Usage in component
import React from 'react';
import { View, Text, Button } from 'react-native';
import useCounter from '../hooks/useCounter';

const CounterScreen = () => {
  const { count, increment, decrement, reset } = useCounter(0);

  return (
    <View style={styles.container}>
      <Text style={styles.countText}>Count: {count}</Text>
      <Button title="Increment" onPress={increment} />
      <Button title="Decrement" onPress={decrement} />
      <Button title="Reset" onPress={reset} />
    </View>
  );
};
```_

### Context API
```javascript
// context/AuthContext.js
import React, { createContext, useContext, useReducer, useEffect } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';

const AuthContext = createContext();

const authReducer = (state, action) => {
  switch (action.type) {
    case 'RESTORE_TOKEN':
      return {
        ...state,
        userToken: action.token,
        isLoading: false,
      };
    case 'SIGN_IN':
      return {
        ...state,
        isSignout: false,
        userToken: action.token,
      };
    case 'SIGN_OUT':
      return {
        ...state,
        isSignout: true,
        userToken: null,
      };
    default:
      return state;
  }
};

export const AuthProvider = ({ children }) => {
  const [state, dispatch] = useReducer(authReducer, {
    isLoading: true,
    isSignout: false,
    userToken: null,
  });

  useEffect(() => {
    const bootstrapAsync = async () => {
      let userToken;

      try {
        userToken = await AsyncStorage.getItem('userToken');
      } catch (e) {
        // Restoring token failed
      }

      dispatch({ type: 'RESTORE_TOKEN', token: userToken });
    };

    bootstrapAsync();
  }, []);

  const authContext = {
    signIn: async (data) => {
      // Simulate API call
      const userToken = 'dummy-auth-token';
      await AsyncStorage.setItem('userToken', userToken);
      dispatch({ type: 'SIGN_IN', token: userToken });
    },
    signOut: async () => {
      await AsyncStorage.removeItem('userToken');
      dispatch({ type: 'SIGN_OUT' });
    },
    signUp: async (data) => {
      // Simulate API call
      const userToken = 'dummy-auth-token';
      await AsyncStorage.setItem('userToken', userToken);
      dispatch({ type: 'SIGN_IN', token: userToken });
    },
  };

  return (
    <AuthContext.Provider value={{ ...state, ...authContext }}>
      {children}
    </AuthContext.Provider>
  );
};

export const useAuth = () => {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
};

// Usage in App.js
import React from 'react';
import { AuthProvider } from './context/AuthContext';
import AppNavigator from './navigation/AppNavigator';

const App = () => {
  return (
    <AuthProvider>
      <AppNavigator />
    </AuthProvider>
  );
};

export default App;
```_

### Redux Setup
```bash
# Install Redux
npm install redux react-redux @reduxjs/toolkit
```_

```javascript
// store/store.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';
import authReducer from './authSlice';

export const store = configureStore({
  reducer: {
    counter: counterReducer,
    auth: authReducer,
  },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

// store/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  value: 0,
};

export const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload;
    },
  },
});

export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;

// Usage in component
import React from 'react';
import { View, Text, Button } from 'react-native';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, incrementByAmount } from '../store/counterSlice';

const CounterScreen = () => {
  const count = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <View style={styles.container}>
      <Text style={styles.countText}>Count: {count}</Text>
      <Button title="+" onPress={() => dispatch(increment())} />
      <Button title="-" onPress={() => dispatch(decrement())} />
      <Button title="+5" onPress={() => dispatch(incrementByAmount(5))} />
    </View>
  );
};

// App.js with Redux Provider
import React from 'react';
import { Provider } from 'react-redux';
import { store } from './store/store';
import AppNavigator from './navigation/AppNavigator';

const App = () => {
  return (
    <Provider store={store}>
      <AppNavigator />
    </Provider>
  );
};

export default App;
```_

## Styling

### StyleSheet
```javascript
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

const StylingExample = () => {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Styling in React Native</Text>
      <View style={styles.box}>
        <Text style={styles.boxText}>Styled Box</Text>
      </View>
      <View style={[styles.box, styles.redBox]}>
        <Text style={[styles.boxText, styles.whiteText]}>Red Box</Text>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#f5f5f5',
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    textAlign: 'center',
    marginBottom: 20,
    color: '#333',
  },
  box: {
    width: 200,
    height: 100,
    backgroundColor: '#007AFF',
    justifyContent: 'center',
    alignItems: 'center',
    marginBottom: 20,
    borderRadius: 10,
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 2,
    },
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
    elevation: 5, // Android shadow
  },
  boxText: {
    color: 'white',
    fontSize: 16,
    fontWeight: '600',
  },
  redBox: {
    backgroundColor: '#FF3B30',
  },
  whiteText: {
    color: 'white',
  },
});

export default StylingExample;
```_

### Flexbox-Layout
```javascript
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

const FlexboxExample = () => {
  return (
    <View style={styles.container}>
      {/* Flex Direction */}
      <View style={styles.section}>
        <Text style={styles.sectionTitle}>Flex Direction: Row</Text>
        <View style={[styles.flexContainer, styles.row]}>
          <View style={[styles.box, styles.box1]} />
          <View style={[styles.box, styles.box2]} />
          <View style={[styles.box, styles.box3]} />
        </View>
      </View>

      {/* Justify Content */}
      <View style={styles.section}>
        <Text style={styles.sectionTitle}>Justify Content: Space Between</Text>
        <View style={[styles.flexContainer, styles.spaceBetween]}>
          <View style={[styles.box, styles.box1]} />
          <View style={[styles.box, styles.box2]} />
          <View style={[styles.box, styles.box3]} />
        </View>
      </View>

      {/* Align Items */}
      <View style={styles.section}>
        <Text style={styles.sectionTitle}>Align Items: Center</Text>
        <View style={[styles.flexContainer, styles.alignCenter]}>
          <View style={[styles.box, styles.box1, { height: 30 }]} />
          <View style={[styles.box, styles.box2, { height: 50 }]} />
          <View style={[styles.box, styles.box3, { height: 40 }]} />
        </View>
      </View>

      {/* Flex */}
      <View style={styles.section}>
        <Text style={styles.sectionTitle}>Flex: 1, 2, 1</Text>
        <View style={[styles.flexContainer, styles.row]}>
          <View style={[styles.box, styles.box1, { flex: 1 }]} />
          <View style={[styles.box, styles.box2, { flex: 2 }]} />
          <View style={[styles.box, styles.box3, { flex: 1 }]} />
        </View>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#f5f5f5',
  },
  section: {
    marginBottom: 30,
  },
  sectionTitle: {
    fontSize: 16,
    fontWeight: 'bold',
    marginBottom: 10,
    color: '#333',
  },
  flexContainer: {
    height: 80,
    backgroundColor: '#e0e0e0',
    borderRadius: 5,
  },
  row: {
    flexDirection: 'row',
  },
  spaceBetween: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingHorizontal: 10,
  },
  alignCenter: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
  },
  box: {
    width: 50,
    height: 50,
    borderRadius: 5,
  },
  box1: {
    backgroundColor: '#FF6B6B',
  },
  box2: {
    backgroundColor: '#4ECDC4',
  },
  box3: {
    backgroundColor: '#45B7D1',
  },
});

export default FlexboxExample;
```_

### Responsive Design
```javascript
import React from 'react';
import { View, Text, StyleSheet, Dimensions } from 'react-native';

const { width, height } = Dimensions.get('window');

const ResponsiveExample = () => {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Responsive Design</Text>

      {/* Percentage-based width */}
      <View style={styles.percentageBox}>
        <Text style={styles.boxText}>50% Width</Text>
      </View>

      {/* Screen dimension-based */}
      <View style={styles.dimensionBox}>
        <Text style={styles.boxText}>Screen Width: {width}</Text>
      </View>

      {/* Aspect ratio */}
      <View style={styles.aspectRatioBox}>
        <Text style={styles.boxText}>Aspect Ratio 16:9</Text>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#f5f5f5',
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    textAlign: 'center',
    marginBottom: 20,
  },
  percentageBox: {
    width: '50%',
    height: 80,
    backgroundColor: '#007AFF',
    justifyContent: 'center',
    alignItems: 'center',
    marginBottom: 20,
    borderRadius: 10,
  },
  dimensionBox: {
    width: width * 0.8,
    height: 80,
    backgroundColor: '#FF3B30',
    justifyContent: 'center',
    alignItems: 'center',
    marginBottom: 20,
    borderRadius: 10,
  },
  aspectRatioBox: {
    width: '100%',
    aspectRatio: 16 / 9,
    backgroundColor: '#34C759',
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 10,
  },
  boxText: {
    color: 'white',
    fontSize: 16,
    fontWeight: '600',
    textAlign: 'center',
  },
});

export default ResponsiveExample;
```_

### Stilierte Komponenten
```bash
# Install styled-components
npm install styled-components
npm install --save-dev @types/styled-components-react-native
```_

```javascript
import React from 'react';
import styled from 'styled-components/native';

const Container = styled.View`
  flex: 1;
  padding: 20px;
  background-color: #f5f5f5;
`;

const Title = styled.Text`
  font-size: 24px;
  font-weight: bold;
  text-align: center;
  margin-bottom: 20px;
  color: #333;
`;

const StyledButton = styled.TouchableOpacity`
  background-color: ${props => props.primary ? '#007AFF' : '#FF3B30'};
  padding: 15px 30px;
  border-radius: 10px;
  margin-bottom: 10px;
  align-items: center;
`;

const ButtonText = styled.Text`
  color: white;
  font-size: 16px;
  font-weight: 600;
`;

const StyledComponentsExample = () => {
  return (
    <Container>
      <Title>Styled Components</Title>

      <StyledButton primary onPress={() => console.log('Primary pressed')}>
        <ButtonText>Primary Button</ButtonText>
      </StyledButton>

      <StyledButton onPress={() => console.log('Secondary pressed')}>
        <ButtonText>Secondary Button</ButtonText>
      </StyledButton>
    </Container>
  );
};

export default StyledComponentsExample;
```_

## APIs und Services

### Fetch API
```javascript
// services/apiService.js
const API_BASE_URL = 'https://jsonplaceholder.typicode.com';

class ApiService {
  static async get(endpoint) {
    try {
      const response = await fetch(`${API_BASE_URL}${endpoint}`);

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      return await response.json();
    } catch (error) {
      console.error('GET request failed:', error);
      throw error;
    }
  }

  static async post(endpoint, data) {
    try {
      const response = await fetch(`${API_BASE_URL}${endpoint}`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      return await response.json();
    } catch (error) {
      console.error('POST request failed:', error);
      throw error;
    }
  }

  static async put(endpoint, data) {
    try {
      const response = await fetch(`${API_BASE_URL}${endpoint}`, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      return await response.json();
    } catch (error) {
      console.error('PUT request failed:', error);
      throw error;
    }
  }

  static async delete(endpoint) {
    try {
      const response = await fetch(`${API_BASE_URL}${endpoint}`, {
        method: 'DELETE',
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      return response.status === 204 ? null : await response.json();
    } catch (error) {
      console.error('DELETE request failed:', error);
      throw error;
    }
  }
}

export default ApiService;

// Usage in component
import React, { useState, useEffect } from 'react';
import { View, Text, FlatList, ActivityIndicator } from 'react-native';
import ApiService from '../services/apiService';

const PostsScreen = () => {
  const [posts, setPosts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetchPosts();
  }, []);

  const fetchPosts = async () => {
    try {
      setLoading(true);
      const data = await ApiService.get('/posts');
      setPosts(data);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  const renderPost = ({ item }) => (
    <View style={styles.postItem}>
      <Text style={styles.postTitle}>{item.title}</Text>
      <Text style={styles.postBody}>{item.body}</Text>
    </View>
  );

  if (loading) {
    return (
      <View style={styles.centered}>
        <ActivityIndicator size="large" color="#007AFF" />
      </View>
    );
  }

  if (error) {
    return (
      <View style={styles.centered}>
        <Text style={styles.errorText}>Error: {error}</Text>
      </View>
    );
  }

  return (
    <FlatList
      data={posts}
      renderItem={renderPost}
      keyExtractor={item => item.id.toString()}
      style={styles.container}
    />
  );
};
```_

### Axios Integration
```bash
# Install Axios
npm install axios
```_

```javascript
// services/httpClient.js
import axios from 'axios';
import AsyncStorage from '@react-native-async-storage/async-storage';

const httpClient = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
  },
});

// Request interceptor
httpClient.interceptors.request.use(
  async (config) => {
    const token = await AsyncStorage.getItem('authToken');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// Response interceptor
httpClient.interceptors.response.use(
  (response) => {
    return response;
  },
  async (error) => {
    if (error.response?.status === 401) {
      // Handle unauthorized access
      await AsyncStorage.removeItem('authToken');
      // Navigate to login screen
    }
    return Promise.reject(error);
  }
);

export default httpClient;

// services/userService.js
import httpClient from './httpClient';

export const userService = {
  getUsers: () => httpClient.get('/users'),
  getUser: (id) => httpClient.get(`/users/${id}`),
  createUser: (userData) => httpClient.post('/users', userData),
  updateUser: (id, userData) => httpClient.put(`/users/${id}`, userData),
  deleteUser: (id) => httpClient.delete(`/users/${id}`),
};
```_

### AsyncStorage
```bash
# Install AsyncStorage
npm install @react-native-async-storage/async-storage

# For iOS
cd ios && pod install && cd ..
```_

```javascript
// utils/storage.js
import AsyncStorage from '@react-native-async-storage/async-storage';

export const storage = {
  // Store data
  setItem: async (key, value) => {
    try {
      const jsonValue = JSON.stringify(value);
      await AsyncStorage.setItem(key, jsonValue);
    } catch (error) {
      console.error('Error storing data:', error);
    }
  },

  // Retrieve data
  getItem: async (key) => {
    try {
      const jsonValue = await AsyncStorage.getItem(key);
      return jsonValue != null ? JSON.parse(jsonValue) : null;
    } catch (error) {
      console.error('Error retrieving data:', error);
      return null;
    }
  },

  // Remove data
  removeItem: async (key) => {
    try {
      await AsyncStorage.removeItem(key);
    } catch (error) {
      console.error('Error removing data:', error);
    }
  },

  // Clear all data
  clear: async () => {
    try {
      await AsyncStorage.clear();
    } catch (error) {
      console.error('Error clearing storage:', error);
    }
  },

  // Get all keys
  getAllKeys: async () => {
    try {
      return await AsyncStorage.getAllKeys();
    } catch (error) {
      console.error('Error getting keys:', error);
      return [];
    }
  },
};

// Usage in component
import React, { useState, useEffect } from 'react';
import { View, Text, TextInput, Button } from 'react-native';
import { storage } from '../utils/storage';

const StorageExample = () => {
  const [name, setName] = useState('');
  const [savedName, setSavedName] = useState('');

  useEffect(() => {
    loadSavedName();
  }, []);

  const loadSavedName = async () => {
    const saved = await storage.getItem('userName');
    if (saved) {
      setSavedName(saved);
    }
  };

  const saveName = async () => {
    await storage.setItem('userName', name);
    setSavedName(name);
    setName('');
  };

  const clearName = async () => {
    await storage.removeItem('userName');
    setSavedName('');
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>AsyncStorage Example</Text>

      <TextInput
        style={styles.input}
        placeholder="Enter your name"
        value={name}
        onChangeText={setName}
      />

      <Button title="Save Name" onPress={saveName} />
      <Button title="Clear Name" onPress={clearName} />

      {savedName ? (
        <Text style={styles.savedText}>Saved Name: {savedName}</Text>
      ) : (
        <Text style={styles.noDataText}>No saved name</Text>
      )}
    </View>
  );
};
```_

## Native Module

### Zugriff auf Geräteeigenschaften
```javascript
// Camera and Image Picker
import { launchImageLibrary, launchCamera } from 'react-native-image-picker';

const ImagePickerExample = () => {
  const [imageUri, setImageUri] = useState(null);

  const selectImage = () => {
    const options = {
      mediaType: 'photo',
      includeBase64: false,
      maxHeight: 2000,
      maxWidth: 2000,
    };

    launchImageLibrary(options, (response) => {
| if (response.didCancel |  | response.error) { |
        console.log('User cancelled or error');
      } else {
        setImageUri(response.assets[0].uri);
      }
    });
  };

  const takePhoto = () => {
    const options = {
      mediaType: 'photo',
      includeBase64: false,
      maxHeight: 2000,
      maxWidth: 2000,
    };

    launchCamera(options, (response) => {
| if (response.didCancel |  | response.error) { |
        console.log('User cancelled or error');
      } else {
        setImageUri(response.assets[0].uri);
      }
    });
  };

  return (
    <View style={styles.container}>
      <Button title="Select from Gallery" onPress={selectImage} />
      <Button title="Take Photo" onPress={takePhoto} />

      {imageUri && (
        <Image source={{ uri: imageUri }} style={styles.image} />
      )}
    </View>
  );
};

// Geolocation
import Geolocation from '@react-native-community/geolocation';

const LocationExample = () => {
  const [location, setLocation] = useState(null);

  const getCurrentLocation = () => {
    Geolocation.getCurrentPosition(
      (position) => {
        setLocation({
          latitude: position.coords.latitude,
          longitude: position.coords.longitude,
        });
      },
      (error) => {
        console.error('Error getting location:', error);
      },
      { enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
    );
  };

  return (
    <View style={styles.container}>
      <Button title="Get Current Location" onPress={getCurrentLocation} />

      {location && (
        <Text>
          Latitude: {location.latitude}, Longitude: {location.longitude}
        </Text>
      )}
    </View>
  );
};

// Permissions
import { PermissionsAndroid, Platform } from 'react-native';

const requestCameraPermission = async () => {
  if (Platform.OS === 'android') {
    try {
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.CAMERA,
        {
          title: 'Camera Permission',
          message: 'App needs camera permission to take photos',
          buttonNeutral: 'Ask Me Later',
          buttonNegative: 'Cancel',
          buttonPositive: 'OK',
        }
      );

      return granted === PermissionsAndroid.RESULTS.GRANTED;
    } catch (err) {
      console.warn(err);
      return false;
    }
  }
  return true; // iOS permissions handled automatically
};
```_

### Erstellung kundenspezifischer Native Module
```javascript
// Android: android/app/src/main/java/com/yourapp/CustomModule.java
package com.yourapp;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;

public class CustomModule extends ReactContextBaseJavaModule {
    CustomModule(ReactApplicationContext context) {
        super(context);
    }

    @Override
    public String getName() {
        return "CustomModule";
    }

    @ReactMethod
    public void multiply(int a, int b, Promise promise) {
        try {
            int result = a * b;
            promise.resolve(result);
        } catch (Exception e) {
            promise.reject("CALCULATION_ERROR", e);
        }
    }
}

// iOS: ios/CustomModule.h
#import <React/RCTBridgeModule.h>

@interface CustomModule : NSObject <RCTBridgeModule>
@end

// iOS: ios/CustomModule.m
#import "CustomModule.h"

@implementation CustomModule

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(multiply:(int)a withB:(int)b
                 withResolver:(RCTPromiseResolveBlock)resolve
                 withRejecter:(RCTPromiseRejectBlock)reject)
{
  NSNumber *result = @(a * b);
  resolve(result);
}

@end

// JavaScript usage
import { NativeModules } from 'react-native';

const { CustomModule } = NativeModules;

const useCustomModule = () => {
  const multiply = async (a, b) => {
    try {
      const result = await CustomModule.multiply(a, b);
      return result;
    } catch (error) {
      console.error('Error in custom module:', error);
      throw error;
    }
  };

  return { multiply };
};
```_

## Leistung

### Optimierungstechnik
```javascript
// React.memo for component optimization
import React, { memo } from 'react';

const ExpensiveComponent = memo(({ data, onPress }) => {
  console.log('ExpensiveComponent rendered');

  return (
    <View style={styles.container}>
      <Text>{data.title}</Text>
      <Button title="Press me" onPress={onPress} />
    </View>
  );
});

// useCallback for function memoization
import React, { useState, useCallback } from 'react';

const ParentComponent = () => {
  const [count, setCount] = useState(0);
  const [data] = useState({ title: 'Static data' });

  const handlePress = useCallback(() => {
    console.log('Button pressed');
  }, []);

  return (
    <View>
      <Text>Count: {count}</Text>
      <Button title="Increment" onPress={() => setCount(count + 1)} />
      <ExpensiveComponent data={data} onPress={handlePress} />
    </View>
  );
};

// useMemo for expensive calculations
import React, { useMemo } from 'react';

const ExpensiveCalculation = ({ items }) => {
  const expensiveValue = useMemo(() => {
    console.log('Calculating expensive value...');
    return items.reduce((sum, item) => sum + item.value, 0);
  }, [items]);

  return <Text>Total: {expensiveValue}</Text>;
};
```_

### FlatList Optimierung
```javascript
import React, { useState, useCallback } from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';

const OptimizedFlatList = () => {
  const [data] = useState(
    Array.from({ length: 1000 }, (_, index) => ({
      id: index.toString(),
      title: `Item ${index}`,
      subtitle: `Subtitle ${index}`,
    }))
  );

  const renderItem = useCallback(({ item }) => (
    <View style={styles.item}>
      <Text style={styles.title}>{item.title}</Text>
      <Text style={styles.subtitle}>{item.subtitle}</Text>
    </View>
  ), []);

  const keyExtractor = useCallback((item) => item.id, []);

  const getItemLayout = useCallback(
    (data, index) => ({
      length: 80, // Item height
      offset: 80 * index,
      index,
    }),
    []
  );

  return (
    <FlatList
      data={data}
      renderItem={renderItem}
      keyExtractor={keyExtractor}
      getItemLayout={getItemLayout}
      initialNumToRender={10}
      maxToRenderPerBatch={10}
      windowSize={10}
      removeClippedSubviews={true}
      updateCellsBatchingPeriod={50}
    />
  );
};

const styles = StyleSheet.create({
  item: {
    height: 80,
    padding: 16,
    borderBottomWidth: 1,
    borderBottomColor: '#eee',
  },
  title: {
    fontSize: 16,
    fontWeight: 'bold',
  },
  subtitle: {
    fontSize: 14,
    color: '#666',
  },
});
```_

### Bildoptimierung
```javascript
import React from 'react';
import { Image, View } from 'react-native';
import FastImage from 'react-native-fast-image';

const ImageOptimization = () => {
  return (
    <View>
      {/* Standard Image with optimization */}
      <Image
        source={{ uri: 'https://example.com/image.jpg' }}
        style={styles.image}
        resizeMode="cover"
        defaultSource={require('./assets/placeholder.png')}
        loadingIndicatorSource={require('./assets/loading.png')}
      />

      {/* FastImage for better performance */}
      <FastImage
        style={styles.image}
        source={{
          uri: 'https://example.com/image.jpg',
          priority: FastImage.priority.normal,
          cache: FastImage.cacheControl.immutable,
        }}
        resizeMode={FastImage.resizeMode.cover}
        onLoad={() => console.log('Image loaded')}
        onError={() => console.log('Image load error')}
      />
    </View>
  );
};
```_

### Bundle Größe Optimierung
```javascript
// metro.config.js
const { getDefaultConfig } = require('metro-config');

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts },
  } = await getDefaultConfig();

  return {
    transformer: {
      babelTransformerPath: require.resolve('react-native-svg-transformer'),
    },
    resolver: {
      assetExts: assetExts.filter(ext => ext !== 'svg'),
      sourceExts: [...sourceExts, 'svg'],
    },
    // Enable bundle splitting
    serializer: {
      createModuleIdFactory: function () {
        return function (path) {
          // Use shorter module IDs
          return path.substr(1).replace(/\//g, '_');
        };
      },
    },
  };
})();

// Dynamic imports for code splitting
const LazyComponent = React.lazy(() => import('./LazyComponent'));

const App = () => {
  return (
    <Suspense fallback={<ActivityIndicator />}>
      <LazyComponent />
    </Suspense>
  );
};
```_

## Prüfung

### Jest Setup
```bash
# Jest is included with React Native by default
# Install additional testing utilities
npm install --save-dev @testing-library/react-native
npm install --save-dev @testing-library/jest-native
```_

```javascript
// __tests__/App.test.js
import React from 'react';
import { render, fireEvent, waitFor } from '@testing-library/react-native';
import '@testing-library/jest-native/extend-expect';
import App from '../App';

describe('App', () => {
  it('renders correctly', () => {
    const { getByText } = render(<App />);
    expect(getByText('Welcome to React Native!')).toBeTruthy();
  });

  it('handles button press', async () => {
    const { getByText, getByTestId } = render(<App />);
    const button = getByTestId('test-button');

    fireEvent.press(button);

    await waitFor(() => {
      expect(getByText('Button pressed!')).toBeTruthy();
    });
  });
});

// Component testing
import React from 'react';
import { render, fireEvent } from '@testing-library/react-native';
import CustomButton from '../components/CustomButton';

describe('CustomButton', () => {
  it('calls onPress when pressed', () => {
    const mockOnPress = jest.fn();
    const { getByText } = render(
      <CustomButton title="Test Button" onPress={mockOnPress} />
    );

    fireEvent.press(getByText('Test Button'));
    expect(mockOnPress).toHaveBeenCalledTimes(1);
  });

  it('is disabled when disabled prop is true', () => {
    const { getByText } = render(
      <CustomButton title="Test Button" disabled={true} />
    );

    const button = getByText('Test Button').parent;
    expect(button).toBeDisabled();
  });
});
```_

### Detox E2E Prüfung
```bash
# Install Detox
npm install --save-dev detox

# Initialize Detox
npx detox init

# Install Detox CLI
npm install -g detox-cli
```_

```javascript
// e2e/firstTest.e2e.js
describe('Example', () => {
  beforeAll(async () => {
    await device.launchApp();
  });

  beforeEach(async () => {
    await device.reloadReactNative();
  });

  it('should have welcome screen', async () => {
    await expect(element(by.id('welcome'))).toBeVisible();
  });

  it('should show hello screen after tap', async () => {
    await element(by.id('hello_button')).tap();
    await expect(element(by.text('Hello!!!'))).toBeVisible();
  });

  it('should show world screen after tap', async () => {
    await element(by.id('world_button')).tap();
    await expect(element(by.text('World!!!'))).toBeVisible();
  });
});

// .detoxrc.json
{
  "testRunner": "jest",
  "runnerConfig": "e2e/config.json",
  "configurations": {
    "ios.sim.debug": {
      "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/YourApp.app",
      "build": "xcodebuild -workspace ios/YourApp.xcworkspace -scheme YourApp -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build",
      "type": "ios.simulator",
      "device": {
        "type": "iPhone 12"
      }
    },
    "android.emu.debug": {
      "binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk",
      "build": "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..",
      "type": "android.emulator",
      "device": {
        "avdName": "Pixel_4_API_30"
      }
    }
  }
}
```_

### Mocking
```javascript
// __mocks__/@react-native-async-storage/async-storage.js
export default {
  setItem: jest.fn(() => Promise.resolve()),
  getItem: jest.fn(() => Promise.resolve(null)),
  removeItem: jest.fn(() => Promise.resolve()),
  clear: jest.fn(() => Promise.resolve()),
  getAllKeys: jest.fn(() => Promise.resolve([])),
};

// __tests__/services/apiService.test.js
import ApiService from '../services/apiService';

// Mock fetch
global.fetch = jest.fn();

describe('ApiService', () => {
  beforeEach(() => {
    fetch.mockClear();
  });

  it('should fetch data successfully', async () => {
    const mockData = { id: 1, title: 'Test Post' };
    fetch.mockResolvedValueOnce({
      ok: true,
      json: async () => mockData,
    });

    const result = await ApiService.get('/posts/1');

    expect(fetch).toHaveBeenCalledWith(
      'https://jsonplaceholder.typicode.com/posts/1'
    );
    expect(result).toEqual(mockData);
  });

  it('should handle fetch errors', async () => {
    fetch.mockRejectedValueOnce(new Error('Network error'));

    await expect(ApiService.get('/posts/1')).rejects.toThrow('Network error');
  });
});
```_

## Debugging

### React Native Debugger
```bash
# Install React Native Debugger
# Download from: https://github.com/jhen0409/react-native-debugger

# Enable debugging in app
# Shake device or press Cmd+D (iOS) / Cmd+M (Android)
# Select "Debug JS Remotely"
```_

### Flipper Integration
```bash
# Flipper is included by default in React Native 0.62+
# Download Flipper desktop app from: https://fbflipper.com/

# Install Flipper plugins
npm install --save-dev react-native-flipper
```_

```javascript
// utils/flipper.js
import { logger } from 'react-native-logs';

const defaultConfig = {
  severity: __DEV__ ? 'debug' : 'error',
  transport: __DEV__ ? logger.consoleTransport : logger.fileAsyncTransport,
  transportOptions: {
    colors: {
      info: 'blueBright',
      warn: 'yellowBright',
      error: 'redBright',
    },
  },
};

const log = logger.createLogger(defaultConfig);

export default log;

// Usage in components
import log from '../utils/flipper';

const MyComponent = () => {
  const handlePress = () => {
    log.debug('Button pressed');
    log.info('User interaction logged');
  };

  return (
    <Button title="Press me" onPress={handlePress} />
  );
};
```_

### Leistungsüberwachung
```javascript
// utils/performance.js
import { InteractionManager } from 'react-native';

export const measurePerformance = (name, fn) => {
  return (...args) => {
    const start = Date.now();

    const result = fn(...args);

    if (result instanceof Promise) {
      return result.finally(() => {
        const end = Date.now();
        console.log(`${name} took ${end - start}ms`);
      });
    } else {
      const end = Date.now();
      console.log(`${name} took ${end - start}ms`);
      return result;
    }
  };
};

export const runAfterInteractions = (fn) => {
  return InteractionManager.runAfterInteractions(fn);
};

// Usage
const expensiveOperation = measurePerformance('expensiveOperation', () => {
  // Expensive computation
  return heavyCalculation();
});

// Run after animations complete
runAfterInteractions(() => {
  // Heavy operation that shouldn't block UI
  processLargeDataSet();
});
```_

### Fehlersuche
```javascript
// components/ErrorBoundary.js
import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false, error: null };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true, error };
  }

  componentDidCatch(error, errorInfo) {
    console.error('Error caught by boundary:', error, errorInfo);

    // Log to crash reporting service
    // crashlytics().recordError(error);
  }

  render() {
    if (this.state.hasError) {
      return (
        <View style={styles.container}>
          <Text style={styles.title}>Something went wrong</Text>
          <Text style={styles.error}>{this.state.error?.message}</Text>
          <Button
            title="Try again"
            onPress={() => this.setState({ hasError: false, error: null })}
          />
        </View>
      );
    }

    return this.props.children;
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  title: {
    fontSize: 20,
    fontWeight: 'bold',
    marginBottom: 10,
  },
  error: {
    fontSize: 14,
    color: 'red',
    textAlign: 'center',
    marginBottom: 20,
  },
});

export default ErrorBoundary;

// Usage in App.js
import ErrorBoundary from './components/ErrorBoundary';

const App = () => {
  return (
    <ErrorBoundary>
      <AppNavigator />
    </ErrorBoundary>
  );
};
```_

## Bereitstellung

### Android Bereitstellung
```bash
# Generate signed APK
cd android
./gradlew assembleRelease

# Generate AAB (Android App Bundle)
./gradlew bundleRelease

# Install release APK
adb install app/build/outputs/apk/release/app-release.apk
```_

```javascript
// android/app/build.gradle
android {
    ...
    signingConfigs {
        release {
            if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
                storeFile file(MYAPP_UPLOAD_STORE_FILE)
                storePassword MYAPP_UPLOAD_STORE_PASSWORD
                keyAlias MYAPP_UPLOAD_KEY_ALIAS
                keyPassword MYAPP_UPLOAD_KEY_PASSWORD
            }
        }
    }
    buildTypes {
        release {
            ...
            signingConfig signingConfigs.release
        }
    }
}

// android/gradle.properties
MYAPP_UPLOAD_STORE_FILE=my-upload-key.keystore
MYAPP_UPLOAD_KEY_ALIAS=my-key-alias
MYAPP_UPLOAD_STORE_PASSWORD=*****
MYAPP_UPLOAD_KEY_PASSWORD=*****
```_

### iOS Bereitstellung
```bash
# Archive for distribution
xcodebuild -workspace ios/MyApp.xcworkspace \
           -scheme MyApp \
           -configuration Release \
           -archivePath ios/build/MyApp.xcarchive \
           archive

# Export IPA
xcodebuild -exportArchive \
           -archivePath ios/build/MyApp.xcarchive \
           -exportPath ios/build \
           -exportOptionsPlist ios/ExportOptions.plist
```_

### Schnelle Automatisierung
```bash
# Install Fastlane
sudo gem install fastlane

# Initialize Fastlane
cd ios && fastlane init
cd android && fastlane init
```_

```ruby
# ios/fastlane/Fastfile
default_platform(:ios)

platform :ios do
  desc "Build and upload to TestFlight"
  lane :beta do
    increment_build_number(xcodeproj: "MyApp.xcodeproj")
    build_app(workspace: "MyApp.xcworkspace", scheme: "MyApp")
    upload_to_testflight
  end

  desc "Build and upload to App Store"
  lane :release do
    increment_build_number(xcodeproj: "MyApp.xcodeproj")
    build_app(workspace: "MyApp.xcworkspace", scheme: "MyApp")
    upload_to_app_store
  end
end

# android/fastlane/Fastfile
default_platform(:android)

platform :android do
  desc "Build and upload to Play Console"
  lane :beta do
    gradle(task: "clean bundleRelease")
    upload_to_play_store(track: 'beta')
  end

  desc "Deploy to Play Store"
  lane :release do
    gradle(task: "clean bundleRelease")
    upload_to_play_store
  end
end
```_

### CodePush (Over-the-Air Updates)
```bash
# Install CodePush CLI
npm install -g code-push-cli

# Install CodePush SDK
npm install --save react-native-code-push

# Register app
code-push app add MyApp-iOS ios react-native
code-push app add MyApp-Android android react-native
```_

```javascript
// App.js with CodePush
import codePush from 'react-native-code-push';

const App = () => {
  return (
    <NavigationContainer>
      <AppNavigator />
    </NavigationContainer>
  );
};

const codePushOptions = {
  checkFrequency: codePush.CheckFrequency.ON_APP_RESUME,
  installMode: codePush.InstallMode.ON_NEXT_RESUME,
};

export default codePush(codePushOptions)(App);

// Release update
// code-push release-react MyApp-iOS ios
// code-push release-react MyApp-Android android
```_

## Plattform-Specific Code

### Plattform Modul
```javascript
import { Platform } from 'react-native';

const PlatformExample = () => {
  return (
    <View style={styles.container}>
      <Text>Platform: {Platform.OS}</Text>
      <Text>Version: {Platform.Version}</Text>

      {Platform.OS === 'ios' && (
        <Text>This is iOS specific content</Text>
      )}

      {Platform.OS === 'android' && (
        <Text>This is Android specific content</Text>
      )}

      <View style={Platform.select({
        ios: styles.iosContainer,
        android: styles.androidContainer,
      })}>
        <Text>Platform specific styling</Text>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
  },
  iosContainer: {
    backgroundColor: '#f0f0f0',
    borderRadius: 10,
  },
  androidContainer: {
    backgroundColor: '#e0e0e0',
    elevation: 5,
  },
});
```_

### Plattformspezifische Dateien
```javascript
// components/Button.ios.js
import React from 'react';
import { TouchableOpacity, Text } from 'react-native';

const Button = ({ title, onPress }) => (
  <TouchableOpacity style={styles.iosButton} onPress={onPress}>
    <Text style={styles.iosButtonText}>{title}</Text>
  </TouchableOpacity>
);

// components/Button.android.js
import React from 'react';
import { TouchableNativeFeedback, Text, View } from 'react-native';

const Button = ({ title, onPress }) => (
  <TouchableNativeFeedback onPress={onPress}>
    <View style={styles.androidButton}>
      <Text style={styles.androidButtonText}>{title}</Text>
    </View>
  </TouchableNativeFeedback>
);

// Usage (React Native automatically picks the right file)
import Button from './components/Button';
```_

### Sicherheit und Sicherheit
```javascript
import React from 'react';
import { SafeAreaView, StatusBar, Platform } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

const SafeAreaExample = () => {
  const insets = useSafeAreaInsets();

  return (
    <SafeAreaView style={styles.container}>
      <StatusBar
        barStyle={Platform.OS === 'ios' ? 'dark-content' : 'light-content'}
        backgroundColor={Platform.OS === 'android' ? '#007AFF' : undefined}
      />

      <View style={{
        paddingTop: insets.top,
        paddingBottom: insets.bottom,
        paddingLeft: insets.left,
        paddingRight: insets.right,
      }}>
        <Text>Content with safe area padding</Text>
      </View>
    </SafeAreaView>
  );
};

Bibliotheken Dritter Teil

Beliebte Bibliotheken

# UI Libraries
npm install react-native-elements
npm install react-native-paper
npm install native-base

# Navigation
npm install @react-navigation/native
npm install @react-navigation/stack
npm install @react-navigation/bottom-tabs

# State Management
npm install redux react-redux @reduxjs/toolkit
npm install zustand
npm install recoil

# Networking
npm install axios
npm install react-query

# Storage
npm install @react-native-async-storage/async-storage
npm install react-native-mmkv

# Media
npm install react-native-image-picker
npm install react-native-video
npm install react-native-sound

# Maps
npm install react-native-maps

# Animations
npm install react-native-reanimated
npm install lottie-react-native

# Forms
npm install react-hook-form
npm install formik

# Utils
npm install react-native-device-info
npm install react-native-permissions
npm install react-native-keychain
```_

### Beispiele für die Integration von Bibliotheken
```javascript
// React Native Elements
import React from 'react';
import { Header, Button, Card } from 'react-native-elements';
import Icon from 'react-native-vector-icons/FontAwesome';

const ElementsExample = () => (
  <View>
    <Header
      centerComponent={{ text: 'MY TITLE', style: { color: '#fff' } }}
      rightComponent={{ icon: 'home', color: '#fff' }}
    />

    <Card title="CARD WITH DIVIDER">
      <Text>Card content goes here</Text>
      <Button
        icon={<Icon name="code" size={15} color="white" />}
        buttonStyle={{ borderRadius: 0, marginLeft: 0, marginRight: 0, marginBottom: 0 }}
        title="VIEW NOW"
      />
    </Card>
  </View>
);

// React Hook Form
import React from 'react';
import { useForm, Controller } from 'react-hook-form';
import { TextInput, Button, Text } from 'react-native';

const FormExample = () => {
  const { control, handleSubmit, formState: { errors } } = useForm();

  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <View>
      <Controller
        control={control}
        rules={{ required: true }}
        render={({ field: { onChange, onBlur, value } }) => (
          <TextInput
            placeholder="Email"
            onBlur={onBlur}
            onChangeText={onChange}
            value={value}
            style={styles.input}
          />
        )}
        name="email"
      />
      {errors.email && <Text>Email is required.</Text>}

      <Button title="Submit" onPress={handleSubmit(onSubmit)} />
    </View>
  );
};

// React Native Reanimated
import React from 'react';
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withSpring,
} from 'react-native-reanimated';

const AnimatedExample = () => {
  const translateX = useSharedValue(0);

  const animatedStyle = useAnimatedStyle(() => {
    return {
      transform: [{ translateX: translateX.value }],
    };
  });

  const handlePress = () => {
    translateX.value = withSpring(translateX.value + 50);
  };

  return (
    <View>
      <Animated.View style={[styles.box, animatedStyle]} />
      <Button title="Move" onPress={handlePress} />
    </View>
  );
};
```_

## Best Practices

### Code Organisation

src/ ├── components/ # Reusable UI components │ ├── common/ # Generic components │ ├── forms/ # Form-specific components │ └── navigation/ # Navigation components ├── screens/ # Screen components │ ├── auth/ # Authentication screens │ ├── main/ # Main app screens │ └── settings/ # Settings screens ├── services/ # API and external services ├── utils/ # Utility functions ├── hooks/ # Custom React hooks ├── context/ # React context providers ├── navigation/ # Navigation configuration ├── assets/ # Images, fonts, etc. ├── constants/ # App constants └── types/ # TypeScript type definitions ```_

Performance Best Practices

```javascript // 1. Use FlatList for large lists const LargeList = ({ data }) => ( } keyExtractor={item => item.id} getItemLayout={(data, index) => ({ length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index, })} removeClippedSubviews={true} maxToRenderPerBatch={10} windowSize={10} /> );

// 2. Optimize images const OptimizedImage = ({ uri }) => ( );

// 3. Use InteractionManager for heavy operations import { InteractionManager } from 'react-native';

const HeavyOperationComponent = () => { useEffect(() => { InteractionManager.runAfterInteractions(() => { // Heavy operation that shouldn't block UI performHeavyOperation(); }); }, []);

return ...; };

// 4. Minimize bridge communication const MinimizeBridge = () => { // Bad: Multiple bridge calls const badExample = () => { Animated.timing(value1, { toValue: 100 }).start(); Animated.timing(value2, { toValue: 200 }).start(); Animated.timing(value3, { toValue: 300 }).start(); };

// Good: Batch operations const goodExample = () => { Animated.parallel([ Animated.timing(value1, { toValue: 100 }), Animated.timing(value2, { toValue: 200 }), Animated.timing(value3, { toValue: 300 }), ]).start(); }; }; ```_

Sicherheit Best Practices

```javascript // 1. Secure storage for sensitive data import { Keychain } from 'react-native-keychain';

const secureStorage = { setItem: async (key, value) => { await Keychain.setInternetCredentials(key, key, value); },

getItem: async (key) => { try { const credentials = await Keychain.getInternetCredentials(key); return credentials ? credentials.password : null; } catch (error) { return null; } },

removeItem: async (key) => { await Keychain.resetInternetCredentials(key); }, };

// 2. Certificate pinning const secureApiCall = async () => { const response = await fetch('https://api.example.com/data', { method: 'GET', headers: { 'Authorization': Bearer ${await secureStorage.getItem('token')}, }, });

return response.json(); };

// 3. Input validation const validateInput = (input) => { // Sanitize and validate user input const sanitized = input.trim().replace(/[<>]/g, '');

if (sanitized.length < 3) { throw new Error('Input too short'); }

return sanitized; }; ```_

Fehlerbehebung

Gemeinsame Themen

```bash

Metro bundler issues

npx react-native start --reset-cache

iOS build issues

cd ios && pod install && cd .. npx react-native run-ios --clean

Android build issues

cd android && ./gradlew clean && cd .. npx react-native run-android --clean

Clear all caches

npx react-native start --reset-cache rm -rf node_modules && npm install cd ios && pod install && cd ..

Fix permission issues (macOS)

sudo chown -R $(whoami) ~/.npm sudo chown -R $(whoami) /usr/local/lib/node_modules ```_

Häufige Fehler

```javascript // Network request failed const handleNetworkError = async () => { try { const response = await fetch('https://api.example.com/data'); return await response.json(); } catch (error) { if (error.message === 'Network request failed') { // Check network connectivity // Verify API endpoint // Check CORS settings } throw error; } };

// Element type is invalid // Usually caused by incorrect import/export // Check component imports and exports

// Cannot read property of undefined const SafeComponent = ({ user }) => { // Use optional chaining return ( {user?.name ?? 'Unknown'} {user?.email ?? 'No email'} ); };

// Memory leaks const ComponentWithCleanup = () => { useEffect(() => { const subscription = someService.subscribe();

return () => {
  // Cleanup subscriptions
  subscription.unsubscribe();
};

}, []);

return ...; }; ```_

--

Zusammenfassung

React Native ist ein leistungsstarker Rahmen für den Aufbau von plattformübergreifenden mobilen Anwendungen, der Folgendes bietet:

  • *Cross-Platform Entwicklung: Schreiben Sie einmal, laufen auf iOS und Android
  • Native Performance: Direkter Zugriff auf native Plattform-APIs und Komponenten
  • *Hot Reloading: Schneller Entwicklungszyklus mit sofortigem Feedback
  • *Rich Ecosystem: Umfangreiche Bibliotheksökosysteme und Gemeinschaftsunterstützung
  • *Familiar Development: Verwenden Sie React-Konzepte und JavaScript/TypeScript
  • *Flexible Architecture: Unterstützt verschiedene staatliche Management- und Navigationslösungen
  • ** Herstellungsfertig**: Verwendet von großen Unternehmen wie Facebook, Instagram und Airbnb

React Native zeichnet sich durch die schnelle mobile App-Entwicklung aus, wobei native Performance und plattformspezifische Nutzererlebnisse erhalten bleiben. Sein reifes Ökosystem, umfassendes Tooling und eine starke Community-Unterstützung machen es zu einer exzellenten Wahl für Teams, die hochwertige mobile Anwendungen effizient aufbauen möchten.

<= <= <= <================================================================================= Funktion copyToClipboard() {\cHFFFF} const commands = document.querySelectorAll('code'); alle Befehle = ''; Befehle. Für jede(cmd) => alle Befehle += cmd.textContent + '\n'); navigator.clipboard.writeText (allCommands); Alarm ('Alle Befehle, die in die Zwischenablage kopiert werden!'); }

Funktion generierenPDF() { Fenster.print(); }