Dezember 21, 2025
17 Min. Lesezeit

Vorstellungsgesprächsfragen für erfahrene React Native Entwickler: Der komplette Leitfaden

interview
career-advice
job-search
Vorstellungsgesprächsfragen für erfahrene React Native Entwickler: Der komplette Leitfaden
MB

Milad Bonakdar

Autor

Meistern Sie die fortgeschrittene React Native Entwicklung mit wichtigen Fragen für Vorstellungsgespräche, die Leistungsoptimierung, native Module, State Management, Tests, Architekturmuster und Cross-Platform Best Practices für erfahrene Entwickler abdecken.


Einführung

Von erfahrenen React Native-Entwicklern wird erwartet, dass sie skalierbare, plattformübergreifende Anwendungen entwerfen, die Leistung optimieren, native Module integrieren und fundierte architektonische Entscheidungen treffen. Diese Rolle erfordert fundiertes Fachwissen in React Native, State Management, nativer Entwicklung und die Fähigkeit, komplexe Herausforderungen der mobilen Entwicklung zu lösen.

Dieser umfassende Leitfaden behandelt wichtige Interviewfragen für erfahrene React Native-Entwickler, die fortgeschrittene React-Konzepte, Leistungsoptimierung, State Management, native Module, Tests und Architekturmuster umfassen. Jede Frage enthält detaillierte Antworten, eine Seltenheitseinschätzung und Schwierigkeitsgrade.


Fortgeschrittenes React & Hooks (5 Fragen)

1. Erkläre useMemo und useCallback. Wann solltest du sie verwenden?

Antwort: Beide Hooks optimieren die Leistung, indem sie Werte/Funktionen memoizieren.

  • useMemo: Memoisiert berechnete Werte (teure Berechnungen)
  • useCallback: Memoisiert Funktionsreferenzen (verhindert Neuerstellung)
  • Wann verwenden: Nur wenn Leistungsprobleme auftreten. Vorzeitige Optimierung kann den Code schwerer lesbar machen.
import { useMemo, useCallback, useState } from 'react';

function ExpensiveComponent({ items, onItemClick }) {
  // useMemo - memoisiert teure Berechnungen
  const sortedItems = useMemo(() => {
    console.log('Sortiere Elemente...');
    return items.sort((a, b) => a.price - b.price);
  }, [items]); // Nur neu berechnen, wenn sich Elemente ändern
  
  // useCallback - memoisiert Funktion
  const handleClick = useCallback((id) => {
    console.log('Element geklickt:', id);
    onItemClick(id);
  }, [onItemClick]); // Nur neu erstellen, wenn sich onItemClick ändert
  
  return (
    <FlatList
      data={sortedItems}
      renderItem={({ item }) => (
        <ItemRow item={item} onClick={handleClick} />
      )}
    />
  );
}

// Kindkomponente mit React.memo
const ItemRow = React.memo(({ item, onClick }) => {
  console.log('Rendere Element:', item.id);
  return (
    <TouchableOpacity onPress={() => onClick(item.id)}>
      <Text>{item.name}</Text>
    </TouchableOpacity>
  );
});

Seltenheit: Sehr häufig Schwierigkeit: Mittel


2. Was ist useRef und was sind seine Anwendungsfälle?

Antwort: useRef erstellt eine mutable Referenz, die über Renderings hinweg erhalten bleibt, ohne Re-Renderings auszulösen.

  • Anwendungsfälle:
    • Zugriff auf DOM-/native Elemente
    • Speichern von mutablen Werten, ohne Re-Rendering auszulösen
    • Speichern vorheriger Werte
    • Speichern von Timern/Intervallen
import { useRef, useEffect } from 'react';
import { TextInput, Animated } from 'react-native';

function FormComponent() {
  const inputRef = useRef(null);
  const previousValue = useRef('');
  const animatedValue = useRef(new Animated.Value(0)).current;
  
  useEffect(() => {
    // Fokussiere Eingabe beim Mounten
    inputRef.current?.focus();
  }, []);
  
  const handleChange = (text) => {
    console.log('Vorheriger:', previousValue.current);
    console.log('Aktuell:', text);
    previousValue.current = text;
  };
  
  const startAnimation = () => {
    Animated.timing(animatedValue, {
      toValue: 1,
      duration: 300,
      useNativeDriver: true,
    }).start();
  };
  
  return (
    <View>
      <TextInput ref={inputRef} onChangeText={handleChange} />
      <Animated.View style={{ opacity: animatedValue }}>
        <Text>Animierter Inhalt</Text>
      </Animated.View>
    </View>
  );
}

// Timer-Beispiel
function Timer() {
  const intervalRef = useRef(null);
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    intervalRef.current = setInterval(() => {
      setCount(c => c + 1);
    }, 1000);
    
    return () => clearInterval(intervalRef.current);
  }, []);
  
  return <Text>{count}</Text>;
}

Seltenheit: Häufig Schwierigkeit: Mittel


3. Erkläre Custom Hooks und wann man sie erstellen sollte.

Antwort: Custom Hooks extrahieren wiederverwendbare zustandsbehaftete Logik in separate Funktionen.

  • Vorteile: Code-Wiederverwendung, Trennung von Belangen, einfacheres Testen
  • Konvention: Muss mit "use" beginnen
// Custom Hook für API-Fetching
function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  
  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch(url);
        const json = await response.json();
        setData(json);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };
    
    fetchData();
  }, [url]);
  
  return { data, loading, error };
}

// Custom Hook für Formularverarbeitung
function useForm(initialValues) {
  const [values, setValues] = useState(initialValues);
  const [errors, setErrors] = useState({});
  
  const handleChange = (name, value) => {
    setValues(prev => ({ ...prev, [name]: value }));
  };
  
  const validate = (validationRules) => {
    const newErrors = {};
    Object.keys(validationRules).forEach(field => {
      const rule = validationRules[field];
      if (rule.required && !values[field]) {
        newErrors[field] = `${field} ist erforderlich`;
      }
    });
    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };
  
  return { values, errors, handleChange, validate };
}

// Verwendung
function UserProfile() {
  const { data, loading, error } = useFetch('https://api.example.com/user');
  const { values, errors, handleChange, validate } = useForm({
    name: '',
    email: '',
  });
  
  if (loading) return <ActivityIndicator />;
  if (error) return <Text>Error: {error}</Text>;
  
  return <Text>{data.name}</Text>;
}

Seltenheit: Häufig Schwierigkeit: Mittel


4. Was ist React Context und wann solltest du es verwenden?

Antwort: Context bietet eine Möglichkeit, Daten durch den Komponentenbaum zu übergeben, ohne Prop-Drilling.

  • Anwendungsfälle: Theme, Authentifizierung, Spracheinstellungen
  • Vorsicht: Kann unnötige Re-Renderings verursachen, wenn nicht sorgfältig verwendet
import { createContext, useContext, useState } from 'react';

// Erstelle Context
const ThemeContext = createContext();
const AuthContext = createContext();

// Theme Provider
function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');
  
  const toggleTheme = () => {
    setTheme(prev => prev === 'light' ? 'dark' : 'light');
  };
  
  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

// Auth Provider
function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  
  const login = async (credentials) => {
    const user = await loginAPI(credentials);
    setUser(user);
  };
  
  const logout = () => {
    setUser(null);
  };
  
  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

// Custom Hooks für Context
function useTheme() {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error('useTheme muss innerhalb von ThemeProvider verwendet werden');
  }
  return context;
}

function useAuth() {
  return useContext(AuthContext);
}

// Verwendung
function App() {
  return (
    <ThemeProvider>
      <AuthProvider>
        <MainApp />
      </AuthProvider>
    </ThemeProvider>
  );
}

function ThemedButton() {
  const { theme, toggleTheme } = useTheme();
  const { user } = useAuth();
  
  return (
    <TouchableOpacity
      style={{ backgroundColor: theme === 'light' ? '#fff' : '#333' }}
      onPress={toggleTheme}
    >
      <Text>{user ? `Hallo, ${user.name}` : 'Gast'}</Text>
    </TouchableOpacity>
  );
}

Seltenheit: Sehr häufig Schwierigkeit: Mittel


5. Erkläre den Unterschied zwischen useEffect und useLayoutEffect.

Antwort: Beide führen Side Effects aus, aber zu unterschiedlichen Zeiten:

  • useEffect: Wird asynchron ausgeführt, nachdem das Rendering auf dem Bildschirm gezeichnet wurde
  • useLayoutEffect: Wird synchron vor dem Zeichnen ausgeführt (blockiert visuelle Updates)
  • Verwende useLayoutEffect wann: Du musst das DOM messen oder visuelles Flimmern verhindern
import { useEffect, useLayoutEffect, useRef, useState } from 'react';

function MeasureComponent() {
  const [height, setHeight] = useState(0);
  const elementRef = useRef(null);
  
  // useLayoutEffect - messen vor dem Zeichnen
  useLayoutEffect(() => {
    if (elementRef.current) {
      const { height } = elementRef.current.measure((x, y, width, height) => {
        setHeight(height);
      });
    }
  }, []);
  
  // useEffect - nach dem Zeichnen
  useEffect(() => {
    console.log('Komponente gerendert');
  }, []);
  
  return (
    <View ref={elementRef}>
      <Text>Höhe: {height}</Text>
    </View>
  );
}

Seltenheit: Mittel Schwierigkeit: Schwer


State Management (4 Fragen)

6. Erkläre Redux und seine Kernprinzipien.

Antwort: Redux ist ein vorhersehbarer State-Container für JavaScript-Apps.

Loading diagram...
  • Kernprinzipien:
    • Single Source of Truth (ein Store)
    • State ist schreibgeschützt (Aktionen zum Ändern dispatch)
    • Änderungen werden mit reinen Funktionen vorgenommen (Reduzierer)
// Aktionstypen
const ADD_TODO = 'ADD_TODO';
const TOGGLE_TODO = 'TOGGLE_TODO';

// Aktions-Ersteller
const addTodo = (text) => ({
  type: ADD_TODO,
  payload: { id: Date.now(), text, completed: false },
});

const toggleTodo = (id) => ({
  type: TOGGLE_TODO,
  payload: id,
});

// Reduzierer
const todosReducer = (state = [], action) => {
  switch (action.type) {
    case ADD_TODO:
      return [...state, action.payload];
    case TOGGLE_TODO:
      return state.map(todo =>
        todo.id === action.payload
          ? { ...todo, completed: !todo.completed }
          : todo
      );
    default:
      return state;
  }
};

// Store
import { createStore } from 'redux';
const store = createStore(todosReducer);

// React Native Komponente
import { useSelector, useDispatch } from 'react-redux';

function TodoList() {
  const todos = useSelector(state => state.todos);
  const dispatch = useDispatch();
  
  return (
    <View>
      <FlatList
        data={todos}
        renderItem={({ item }) => (
          <TouchableOpacity onPress={() => dispatch(toggleTodo(item.id))}>
            <Text style={{ textDecorationLine: item.completed ? 'line-through' : 'none' }}>
              {item.text}
            </Text>
          </TouchableOpacity>
        )}
      />
      <Button title="Hinzufügen" onPress={() => dispatch(addTodo('Neue Aufgabe'))} />
    </View>
  );
}

Seltenheit: Sehr häufig Schwierigkeit: Schwer


7. Was ist Redux Toolkit und wie vereinfacht es Redux?

Antwort: Redux Toolkit ist die offiziell empfohlene Methode, um Redux-Logik zu schreiben.

  • Vorteile:
    • Weniger Boilerplate
    • Eingebautes Immer für immutable Updates
    • Enthält Redux Thunk
    • Bessere TypeScript-Unterstützung
import { createSlice, configureStore } from '@reduxjs/toolkit';

// Slice (kombiniert Aktionen und Reduzierer)
const todosSlice = createSlice({
  name: 'todos',
  initialState: [],
  reducers: {
    addTodo: (state, action) => {
      // Immer erlaubt "mutierenden" Code
      state.push({
        id: Date.now(),
        text: action.payload,
        completed: false,
      });
    },
    toggleTodo: (state, action) => {
      const todo = state.find(t => t.id === action.payload);
      if (todo) {
        todo.completed = !todo.completed;
      }
    },
  },
});

export const { addTodo, toggleTodo } = todosSlice.actions;

// Store
const store = configureStore({
  reducer: {
    todos: todosSlice.reducer,
  },
});

// Async Thunk
import { createAsyncThunk } from '@reduxjs/toolkit';

export const fetchTodos = createAsyncThunk(
  'todos/fetchTodos',
  async () => {
    const response = await fetch('https://api.example.com/todos');
    return response.json();
  }
);

const todosSlice = createSlice({
  name: 'todos',
  initialState: { items: [], loading: false, error: null },
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(fetchTodos.pending, (state) => {
        state.loading = true;
      })
      .addCase(fetchTodos.fulfilled, (state, action) => {
        state.loading = false;
        state.items = action.payload;
      })
      .addCase(fetchTodos.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message;
      });
  },
});

Seltenheit: Häufig Schwierigkeit: Mittel


8. Was sind Alternativen zu Redux für State Management?

Antwort: Es gibt mehrere State-Management-Lösungen:

  • Context API + useReducer: Eingebaut, gut für einfache Apps
  • MobX: Observable-basiert, weniger Boilerplate
  • Zustand: Minimal, Hooks-basiert
  • Recoil: Atom-basiert, von Facebook
  • Jotai: Primitive Atome
// Zustand Beispiel
import create from 'zustand';

const useStore = create((set) => ({
  todos: [],
  addTodo: (text) => set((state) => ({
    todos: [...state.todos, { id: Date.now(), text, completed: false }],
  })),
  toggleTodo: (id) => set((state) => ({
    todos: state.todos.map(todo =>
      todo.id === id ? { ...todo, completed: !todo.completed } : todo
    ),
  })),
}));

// Verwendung
function TodoList() {
  const { todos, addTodo, toggleTodo } = useStore();
  
  return (
    <View>
      <FlatList
        data={todos}
        renderItem={({ item }) => (
          <TouchableOpacity onPress={() => toggleTodo(item.id)}>
            <Text>{item.text}</Text>
          </TouchableOpacity>
        )}
      />
    </View>
  );
}

Seltenheit: Häufig Schwierigkeit: Mittel


9. Wie handhabst du Side Effects in Redux?

Antwort: Verwende Middleware für asynchrone Operationen:

  • Redux Thunk: Funktionen, die Funktionen zurückgeben
  • Redux Saga: Generator-basiert, leistungsfähiger
  • Redux Observable: RxJS-basiert
// Redux Thunk
const fetchUser = (userId) => async (dispatch) => {
  dispatch({ type: 'FETCH_USER_REQUEST' });
  
  try {
    const response = await fetch(`https://api.example.com/users/${userId}`);
    const user = await response.json();
    dispatch({ type: 'FETCH_USER_SUCCESS', payload: user });
  } catch (error) {
    dispatch({ type: 'FETCH_USER_FAILURE', payload: error.message });
  }
};

// Verwendung
dispatch(fetchUser(123));

// Redux Saga
import { call, put, takeEvery } from 'redux-saga/effects';

function* fetchUserSaga(action) {
  try {
    const user = yield call(fetch, `https://api.example.com/users/${action.payload}`);
    const data = yield call([user, 'json']);
    yield put({ type: 'FETCH_USER_SUCCESS', payload: data });
  } catch (error) {
    yield put({ type: 'FETCH_USER_FAILURE', payload: error.message });
  }
}

function* watchFetchUser() {
  yield takeEvery('FETCH_USER_REQUEST', fetchUserSaga);
}

Seltenheit: Häufig Schwierigkeit: Schwer


Leistungsoptimierung (5 Fragen)

10. Wie optimierst du die Leistung von FlatList?

Antwort: Mehrere Strategien verbessern das Scrollen von FlatList:

  1. Verwende keyExtractor: Stelle eindeutige Schlüssel bereit
  2. getItemLayout: Überspringe die Messung für Elemente mit fester Höhe
  3. removeClippedSubviews: Unmounten von Ansichten außerhalb des Bildschirms (Android)
  4. maxToRenderPerBatch: Steuere die Batch-Größe
  5. windowSize: Steuere das gerenderte Fenster
  6. initialNumToRender: Anzahl der Elemente, die anfänglich gerendert werden sollen
  7. Memoisiere renderItem: Verhindere unnötige Re-Renderings
import React, { memo, useCallback } from 'react';

const ITEM_HEIGHT = 80;

// Memoized Item-Komponente
const ListItem = memo(({ item, onPress }) => {
  return (
    <TouchableOpacity onPress={() => onPress(item.id)} style={{ height: ITEM_HEIGHT }}>
      <Text>{item.name}</Text>
    </TouchableOpacity>
  );
});

function OptimizedList({ data }) {
  const handlePress = useCallback((id) => {
    console.log('Gedrückt:', id);
  }, []);
  
  const renderItem = useCallback(({ item }) => (
    <ListItem item={item} onPress={handlePress} />
  ), [handlePress]);
  
  const keyExtractor = useCallback((item) => item.id.toString(), []);
  
  const getItemLayout = useCallback((data, index) => ({
    length: ITEM_HEIGHT,
    offset: ITEM_HEIGHT * index,
    index,
  }), []);
  
  return (
    <FlatList
      data={data}
      renderItem={renderItem}
      keyExtractor={keyExtractor}
      getItemLayout={getItemLayout}
      removeClippedSubviews={true}
      maxToRenderPerBatch={10}
      updateCellsBatchingPeriod={50}
      initialNumToRender={10}
      windowSize={5}
    />
  );
}

Seltenheit: Sehr häufig Schwierigkeit: Mittel


11. Was ist die React Native Bridge und wie beeinflusst sie die Leistung?

Antwort: Die Bridge ist die Kommunikationsschicht zwischen JavaScript und nativem Code.

  • Wie es funktioniert:
    • JavaScript läuft in einem separaten Thread
    • Native Module laufen in nativen Threads
    • Die Bridge serialisiert Daten zwischen ihnen (JSON)
  • Leistungsauswirkungen:
    • Die Bridge-Kommunikation ist asynchron
    • Serialisierungs-Overhead
    • Kann bei häufiger Kommunikation zum Engpass werden
  • Lösungen:
    • Minimiere Bridge-Übergänge
    • Batch-Operationen
    • Verwende native Animationen (umgehe die Bridge)
    • Neue Architektur (JSI) entfernt die Bridge
// Schlecht - häufige Bridge-Übergänge
const BadAnimation = () => {
  const [position, setPosition] = useState(0);
  
  useEffect(() => {
    const interval = setInterval(() => {
      setPosition(p => p + 1); // Bridge-Übergang bei jedem Frame!
    }, 16);
    return () => clearInterval(interval);
  }, []);
  
  return <View style={{ transform: [{ translateX: position }] }} />;
};

// Gut - native Animation (keine Bridge)
const GoodAnimation = () => {
  const translateX = useRef(new Animated.Value(0)).current;
  
  useEffect(() => {
    Animated.timing(translateX, {
      toValue: 100,
      duration: 1000,
      useNativeDriver: true, // Läuft im nativen Thread!
    }).start();
  }, []);
  
  return <Animated.View style={{ transform: [{ translateX }] }} />;
};

Seltenheit: Häufig Schwierigkeit: Schwer


12. Wie verhinderst du unnötige Re-Renderings?

Antwort: Mehrere Techniken verhindern unnötige Renderings:

  1. React.memo: Memoisiere Komponenten
  2. useMemo/useCallback: Memoisiere Werte/Funktionen
  3. Korrekte Key-Props: Helfen React, Änderungen zu identifizieren
  4. Vermeide Inline-Objekte/Arrays: Erstelle neue Referenzen
  5. Teile Komponenten auf: Kleinere, fokussierte Komponenten
// Schlecht - erstellt bei jedem Rendering ein neues Objekt
function BadComponent() {
  return <ChildComponent style={{ margin: 10 }} />; // Neues Objekt!
}

// Gut - stabile Referenz
const styles = StyleSheet.create({
  container: { margin: 10 },
});

function GoodComponent() {
  return <ChildComponent style={styles.container} />;
}

// React.memo mit benutzerdefiniertem Vergleich
const ExpensiveComponent = React.memo(
  ({ data, onPress }) => {
    console.log('Rendere ExpensiveComponent');
    return (
      <View>
        <Text>{data.name}</Text>
        <Button onPress={onPress} />
      </View>
    );
  },
  (prevProps, nextProps) => {
    // Benutzerdefinierter Vergleich - nur Re-Rendering, wenn sich data.id geändert hat
    return prevProps.data.id === nextProps.data.id;
  }
);

// Teile Komponenten auf, um Re-Renderings zu isolieren
function ParentComponent() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');
  
  return (
    <View>
      {/* Nur Re-Rendering, wenn sich count ändert */}
      <CountDisplay count={count} />
      
      {/* Nur Re-Rendering, wenn sich text ändert */}
      <TextDisplay text={text} />
      
      <Button onPress={() => setCount(c => c + 1)} />
    </View>
  );
}

const CountDisplay = React.memo(({ count }) => <Text>{count}</Text>);
const TextDisplay = React.memo(({ text }) => <Text>{text}</Text>);

Seltenheit: Sehr häufig Schwierigkeit: Mittel


13. Wie optimierst du Bilder in React Native?

Antwort: Bildoptimierung ist entscheidend für die Leistung:

  1. Größe von Bildern ändern: Verwende geeignete Abmessungen
  2. Bilder zwischenspeichern: Verwende Bibliotheken wie react-native-fast-image
  3. Lazy Loading: Lade Bilder bei Bedarf
  4. Progressives Laden: Zeige zuerst einen Platzhalter
  5. Verwende das WebP-Format: Bessere Komprimierung
import FastImage from 'react-native-fast-image';

function OptimizedImage({ uri }) {
  return (
    <FastImage
      source={{
        uri,
        priority: FastImage.priority.normal,
        cache: FastImage.cacheControl.immutable,
      }}
      resizeMode={FastImage.resizeMode.cover}
      style={{ width: 200, height: 200 }}
    />
  );
}

// Progressives Laden von Bildern
function ProgressiveImage({ thumbnailUri, fullUri }) {
  const [imageLoaded, setImageLoaded] = useState(false);
  
  return (
    <View>
      <Image
        source={{ uri: thumbnailUri }}
        style={styles.image}
        blurRadius={imageLoaded ? 0 : 5}
      />
      <Image
        source={{ uri: fullUri }}
        style={[styles.image, { opacity: imageLoaded ? 1 : 0 }]}
        onLoad={() => setImageLoaded(true)}
      />
    </View>
  );
}

// Image Prefetching
import { Image } from 'react-native';

const prefetchImages = async (urls) => {
  const promises = urls.map(url => Image.prefetch(url));
  await Promise.all(promises);
};

Seltenheit: Häufig Schwierigkeit: Mittel


14. Welche Tools verwendest du für das Performance-Profiling?

Antwort: Mehrere Tools helfen, Leistungsprobleme zu identifizieren:

  • React DevTools Profiler: Renderzeiten von Komponenten
  • Flipper: Debugging- und Profiling-Tool
  • Performance Monitor: Eingebauter FPS-Monitor
  • Systrace: Android Performance Tracing
  • Instruments: iOS Performance Profiling
// Aktiviere den Performance-Monitor im Dev-Modus
import { LogBox } from 'react-native';

if (__DEV__) {
  // Zeige den Performance-Monitor an
  require('react-native').unstable_enableLogBox();
}

// Messe die Renderzeit von Komponenten
import { Profiler } from 'react';

function onRenderCallback(
  id,
  phase,
  actualDuration,
  baseDuration,
  startTime,
  commitTime
) {
  console.log(`${id} (${phase}) dauerte ${actualDuration}ms`);
}

function App() {
  return (
    <Profiler id="App" onRender={onRenderCallback}>
      <MyComponent />
    </Profiler>
  );
}

// Benutzerdefinierte Performance-Tracking
const measurePerformance = (name, fn) => {
  const start = performance.now();
  const result = fn();
  const end = performance.now();
  console.log(`${name} dauerte ${end - start}ms`);
  return result;
};

Seltenheit: Häufig Schwierigkeit: Mittel


Native Module & Plattformspezifisch (4 Fragen)

15. Wie erstellst du ein natives Modul in React Native?

Antwort: Native Module ermöglichen die Verwendung von plattformspezifischem Code.

// iOS (Objective-C) - CalendarManager.m
#import "CalendarManager.h"
#import <React/RCTLog.h>

@implementation CalendarManager

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location)
{
  RCTLogInfo(@"Creating event %@ at %@", name, location);
}

@end

// Android (Java) - CalendarModule.java
package com.myapp;

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

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

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

  @ReactMethod
  public void addEvent(String name, String location) {
    Log.d("CalendarModule", "Creating event " + name + " at " + location);
  }
}

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

const { CalendarManager } = NativeModules;

function MyComponent() {
  const createEvent = () => {
    CalendarManager.addEvent('Meeting', 'Office');
  };
  
  return <Button title="Event erstellen" onPress={createEvent} />;
}

Seltenheit: Mittel Schwierigkeit: Schwer


16. Wie handhabst du plattformspezifischen Code?

Antwort: Mehrere Ansätze für plattformspezifischen Code:

  1. Plattformmodul: Überprüfe die Plattform zur Laufzeit
  2. Plattformspezifische Dateien: .ios.js und .android.js
  3. Platform.select: Wähle Werte basierend auf der Plattform aus
import { Platform } from 'react-native';

// Plattformmodul
const styles = StyleSheet.create({
  container: {
    paddingTop: Platform.OS === 'ios' ? 20 : 0,
  },
});

// Platform.select
const styles = StyleSheet.create({
  container: {
    ...Platform.select({
      ios: {
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.3,
      },
      android: {
        elevation: 4,
      },
    }),
  },
});

// Plattformspezifische Dateien
// Button.ios.js
export default function Button() {
  return <Text>iOS Button</Text>;
}

// Button.android.js
export default function Button() {
  return <Text>Android Button</Text>;
}

// Verwendung - wählt automatisch die richtige Datei aus
import Button from './Button';

// Plattformversionsprüfung
if (Platform.Version >= 21) {
  // Android API 21+
}

Seltenheit: Sehr häufig Schwierigkeit: Einfach


17. Was ist die neue Architektur (Fabric und TurboModule)?

Antwort: Die neue Architektur verbessert die Leistung von React Native:

  • Fabric: Neues Rendering-System
    • Synchrones Layout
    • Bessere Interoperabilität mit nativen Ansichten
    • Typsicherheit
  • TurboModule: Neues natives Modulsystem
    • Lazy Loading
    • JSI (JavaScript Interface) - direkte C++-Kommunikation
    • Keine Bridge-Serialisierung

Vorteile:

  • Schnellerer Start
  • Geringere Speichernutzung
  • Synchrone native Aufrufe
  • Bessere Typsicherheit

Seltenheit: Mittel Schwierigkeit: Schwer


18. Wie handhabst du Deep Linking in React Native?

Antwort: Deep Linking ermöglicht das Öffnen bestimmter Bildschirme über URLs.

import { Linking } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';

// Konfiguriere Deep Linking
const linking = {
  prefixes: ['myapp://', 'https://myapp.com'],
  config: {
    screens: {
      Home: 'home',
      Profile: 'profile/:id',
      Settings: 'settings',
    },
  },
};

function App() {
  return (
    <NavigationContainer linking={linking}>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Profile" component={ProfileScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

// Behandle eingehende Links
useEffect(() => {
  const handleUrl = ({ url }) => {
    console.log('Geöffnet mit URL:', url);
    // myapp://profile/123
  };
  
  // App wurde über Link geöffnet
  Linking.getInitialURL().then(url => {
    if (url) handleUrl({ url });
  });
  
  // App bereits geöffnet, neuer Link
  const subscription = Linking.addEventListener('url', handleUrl);
  
  return () => subscription.remove();
}, []);

// Öffne URL programmgesteuert
const openURL = async (url) => {
  const supported = await Linking.canOpenURL(url);
  if (supported) {
    await Linking.openURL(url);
  }
};

Seltenheit: Häufig Schwierigkeit: Mittel


Testen (3 Fragen)

19. Wie testest du React Native-Komponenten?

Antwort: Verwende Testbibliotheken wie Jest und React Native Testing Library.

import { render, fireEvent, waitFor } from '@testing-library/react-native';
import Counter from './Counter';

describe('Counter', () => {
  it('rendert den initialen Zählerwert', () => {
    const { getByText } = render(<Counter />);
    expect(getByText('Zähler: 0')).toBeTruthy();
  });
  
  it('erhöht
Newsletter subscription

Wöchentliche Karrieretipps, die wirklich funktionieren

Erhalten Sie die neuesten Einblicke direkt in Ihr Postfach

Decorative doodle

Erstellen Sie einen Lebenslauf, der Sie 60% schneller einstellt

Erstellen Sie in wenigen Minuten einen maßgeschneiderten, ATS-freundlichen Lebenslauf, der nachweislich 6-mal mehr Vorstellungsgespräche vermittelt.

Einen besseren Lebenslauf erstellen

Diesen Beitrag teilen

Werden Sie 50% Schneller Eingestellt

Arbeitssuchende mit professionellen, KI-optimierten Lebensläufen finden in durchschnittlich 5 Wochen eine Stelle, verglichen mit den üblichen 10. Hören Sie auf zu warten und beginnen Sie mit Vorstellungsgesprächen.