Master these 31 carefully curated interview questions to ace your next React native interview.
React Native is a framework for building native mobile apps for iOS and Android using React and JavaScript.
Uses React components that map to native UI elements (not WebView). Single codebase for both platforms. Hot reloading for fast development. Access native APIs via modules. Used by: Meta, Instagram, Shopify, Discord. New Architecture: Fabric renderer, TurboModules, JSI for better performance.
React targets web browsers (DOM); React Native targets mobile platforms (native UI components) with platform-specific APIs.
React: renders to DOM, uses HTML/CSS. React Native: renders to native views (UIView/Android.View), uses StyleSheet (Flexbox-based, no CSS). Same component model, hooks, state management. Platform-specific code: Platform.OS, .ios.js/.android.js files. Navigation: React Router (web) vs React Navigation (native).
Expo provides managed workflow with pre-built native modules; bare RN gives full native access but requires manual configuration.
Expo: quick setup, OTA updates, pre-built modules (camera, notifications), limited native customization. Bare: full native access, custom native modules, manual linking, more complex setup. Expo can eject to bare. EAS Build: cloud builds without local setup. Most new projects start with Expo.
React Navigation is the standard library with Stack, Tab, and Drawer navigators for screen management and transitions.
Navigators: Stack (push/pop screens), Bottom Tabs, Drawer, Material Top Tabs. Deep linking: map URLs to screens. Navigation state: useNavigation() hook, navigation.navigate(). Params: pass data between screens. TypeScript: typed navigation for route safety. Alternative: Expo Router (file-based routing like Next.js).
Same as React: useState, useContext, Redux Toolkit, Zustand. AsyncStorage for persistence, React Query for server state.
Local state: useState, useReducer. Global: Context API, Redux Toolkit, Zustand (lightweight), Jotai. Server state: React Query, SWR. Persistence: AsyncStorage, MMKV (faster). Offline: WatermelonDB, Realm. State hydration: persist state across app restarts. Same patterns as React web.
Use FlatList for lists, memoize components, avoid inline styles, use native driver for animations, and profile with Flipper.
Key: (1) FlatList/SectionList for long lists (virtualizes). (2) React.memo, useMemo, useCallback. (3) Avoid inline object/function creation in render. (4) useNativeDriver: true for animations. (5) Hermes engine (faster startup). (6) Image optimization: FastImage library. (7) Profile with Flipper, React DevTools. (8) Reduce bridge crossings (New Architecture eliminates bridge).
New Architecture replaces the Bridge with JSI, Fabric renderer, and TurboModules for synchronous native access and better performance.
Components: (1) JSI (JavaScript Interface): direct C++ bindings, no JSON serialization. (2) Fabric: new rendering system, synchronous layout. (3) TurboModules: lazy-loaded native modules, type-safe. (4) Codegen: generates native code from JS specs. Benefits: synchronous calls, concurrent rendering, reduced memory, type safety. Migration: opt-in, gradual adoption. Available in React Native 0.72+.
Enable Hermes, profile with Flipper, optimize lists with FlatList, reduce re-renders, and use native driver for animations.
Steps: (1) Enable Hermes engine (faster JS). (2) Profile with Flipper (Performance plugin). (3) Check for unnecessary re-renders (React DevTools). (4) Optimize images (resize, cache). (5) FlatList with getItemLayout. (6) Avoid expensive operations on JS thread. (7) Use InteractionManager for deferred work. (8) New Architecture for reduced overhead.
Instagram uses React Native for specific features (Explore, notifications) alongside native code, achieving 85-99% code sharing.
Instagram's approach: (1) Not full RN rewrite — selective screens. (2) Share 85-99% code between iOS/Android for RN screens. (3) Brownfield integration: RN screens within native app. (4) Custom infrastructure for navigation between native and RN. (5) Performance optimizations: pre-loading JS bundles, component caching. Key lesson: incremental adoption works better than full rewrite.
React renders to browser DOM with HTML elements; React Native renders to native mobile components using native UI primitives.
React: renders HTML elements (div, span, p) to browser DOM. Uses CSS for styling. React Native: renders native components (View, Text, Image) to iOS UIKit/Android Views. Uses StyleSheet (flexbox-based, no CSS cascade). Shared: component model, JSX, state management, hooks, context. Different: navigation (React Router vs React Navigation), storage (localStorage vs AsyncStorage), animations (CSS vs Animated/Reanimated). Code sharing: up to 70-80% logic shared using platform-specific files (.ios.js, .android.js).
The bridge serializes JavaScript-to-native communication as async JSON messages between JS thread and native threads.
Old architecture: JS thread runs React logic, Native modules thread runs platform code, UI thread renders. Bridge: async JSON serialization between threads — bottleneck for frequent updates. New Architecture (Fabric + TurboModules): JSI (JavaScript Interface) enables synchronous native calls without JSON serialization. Fabric: new rendering system with synchronous layout. TurboModules: lazy-loaded native modules with direct JSI access. Hermes engine: optimized for React Native (bytecode, faster startup). Migration: gradual, Interop Layer supports old modules.
React Navigation is the standard library providing Stack, Tab, and Drawer navigators with deep linking and gesture support.
React Navigation: createStackNavigator (screen transitions), createBottomTabNavigator, createDrawerNavigator. Usage: NavigationContainer wraps app, screens defined in navigator. navigation.navigate('Screen', { params }). Deep linking: linking configuration maps URLs to screens. Nested navigators: tab navigator inside stack. Expo Router: file-based routing inspired by Next.js. Options: headerShown, tabBarIcon, gestureEnabled. Type safety: ParamList type for route params. Performance: use native stack navigator (react-native-screens) for native transitions.
Use React Context for simple state, Zustand/Redux for complex global state, React Query for server state, and MMKV for persistence.
Options: (1) useState/useReducer: component-local state. (2) Context API: simple shared state (theme, auth). (3) Zustand: lightweight, hook-based, minimal boilerplate. (4) Redux Toolkit: predictable, powerful DevTools, middleware. (5) Jotai/Recoil: atomic state management. (6) React Query/TanStack Query: server state (caching, sync, pagination). (7) Persistence: react-native-mmkv (fast key-value), AsyncStorage (slower). Recommendation: Zustand for app state + React Query for server state is modern best practice. Avoid over-engineering — start simple.
Use FlatList for lists, memoize components, minimize re-renders, optimize images, use Hermes engine, and profile with Flipper.
Lists: FlatList with keyExtractor, getItemLayout (skip measurement), windowSize, removeClippedSubviews. Components: React.memo, useMemo, useCallback to prevent unnecessary re-renders. Images: FastImage (caching), proper resizing, WebP format. Animations: Reanimated (runs on UI thread) over Animated. JS engine: Hermes (faster startup, lower memory). Navigation: native-stack (native transitions). Avoid: inline functions in render, frequent state updates, large component trees. Tools: Flipper (profiler), React DevTools, Systrace. Bundle: metro.config.js for tree shaking.
Native modules expose platform-specific functionality (camera, sensors) to JavaScript via the bridge or JSI.
Purpose: access native APIs not available in React Native core. Old module: create iOS (Objective-C/Swift) and Android (Java/Kotlin) classes, register with bridge, call from JS. TurboModules (new architecture): define .js spec → codegen generates native interfaces → implement in native code. Direct JSI access for synchronous calls. Community modules: react-native-camera, react-native-maps, etc. Expo modules API: create native modules compatible with Expo. Platform-specific: Platform.OS === 'ios', .ios.js / .android.js file extensions.
New Architecture includes Fabric (new renderer), TurboModules (lazy native modules), JSI (synchronous native bridge), and CodeGen.
JSI (JavaScript Interface): C++ layer replacing JSON bridge — direct, synchronous native calls. Fabric: new rendering system — synchronous layout on any thread, concurrent rendering support, view flattening. TurboModules: native modules loaded lazily (not all at startup), type-safe via codegen from JS specs. Codegen: generates native interfaces from TypeScript specs — type safety between JS and native. Benefits: better performance, lower memory, concurrent rendering, shared C++ code between platforms. React Native 0.74+: new architecture enabled by default.
React Native provides Animated API (JS-driven), LayoutAnimation (auto-animate layout changes), and Reanimated (worklet-based, 60fps).
Animated: Animated.Value, Animated.timing/spring/decay, interpolate. Runs on JS thread by default — can lag. useNativeDriver: true offloads to native thread (transform, opacity only). LayoutAnimation: auto-animate layout changes (simple but limited control). Reanimated 2/3: worklets run on UI thread via JSI — true 60fps. useSharedValue, useAnimatedStyle, withTiming/withSpring. Gesture Handler: Swipeable, Pan, Pinch with Reanimated. Skia: canvas-based animations, custom drawing. Best practice: Reanimated for production animations, Animated for simple cases.
Use react-native-firebase (FCM) for Android, APNs for iOS, with notification handling for foreground, background, and quit states.
Firebase Cloud Messaging (FCM): works on both platforms. Setup: install @react-native-firebase/messaging. Permissions: requestUserPermission() on iOS. Token: getToken() → send to backend. Foreground: onMessage listener. Background: setBackgroundMessageHandler. App quit: getInitialNotification. Local notifications: @notifee/react-native — scheduling, badges, sound. Deep linking: notification opens specific screen. Topics: subscribe users to channels. Data notifications: silent push for background sync. Analytics: track notification open rates. Testing: Firebase console or Postman to FCM API.
Use crash reporting (Sentry/Crashlytics), reproduce on that device/OS, check native logs, and test with real devices.
Steps: (1) Crash analytics: Sentry, Firebase Crashlytics — stack trace, device info, OS version. (2) Reproduce: get exact device model, OS version, use device farm (BrowserStack, AWS). (3) Native logs: adb logcat (Android), Xcode console (iOS). (4) Common causes: memory issues on low-end devices, native module incompatibility, large images, deep nesting. (5) Hermes: check bytecode compatibility. (6) Debug JS: Chrome DevTools, Flipper. (7) Test matrix: different screen sizes, OS versions, RAM. (8) OTA updates: CodePush for quick fixes. (9) ProGuard/R8 (Android): check obfuscation mapping.
Use local storage for data persistence, queue failed network requests, sync when online, and show stale data with indicators.
Storage: MMKV (fast key-value), WatermelonDB (SQLite ORM for large datasets), Realm (object database). Network detection: @react-native-community/netinfo. Offline-first: always read from local DB, sync with server when online. Conflict resolution: last-write-wins, merge strategy, or server-side resolution. Request queue: store failed API calls, retry on reconnect. UI: show cached data with 'offline' banner, disable actions requiring network. Optimistic updates: update UI immediately, handle server rejection. React Query: supports offline mutations queue.
Expo is a framework/platform on top of React Native providing managed workflow, pre-built native modules, EAS build services, and OTA updates.
Expo managed: no native code needed, pre-configured common modules (camera, location, notifications), expo go app for development. Expo bare/prebuild: eject to access native code while keeping Expo tools. EAS Build: cloud builds without Xcode/Android Studio. EAS Submit: app store submission. EAS Update: over-the-air JS updates. Expo Router: file-based routing. When to use Expo: most apps (recommended default). When to avoid: highly custom native code, unsupported native libraries (rare now with Expo modules). Expo SDK 51+ supports most native module needs through config plugins.
Use flexbox layouts, Dimensions API, percentage values, Platform-specific code, and responsive utility libraries.
Flexbox: flex: 1 for proportional sizing, flexDirection, justifyContent, alignItems. Dimensions: const { width } = Dimensions.get('window'). useWindowDimensions hook for reactive sizing. Responsive: percentage widths, aspect ratios. Libraries: react-native-responsive-screen for dp-based sizing. Platform: Platform.select({ ios: {}, android: {} }). Tablets: adjust layout breakpoints. Safe area: react-native-safe-area-context for notches/status bars. Pixel ratio: PixelRatio.get() for density-aware sizing. Testing: use device simulators with different screen sizes.
Use React Hook Form for form state, Zod/Yup for validation, TextInput for inputs, and KeyboardAvoidingView for keyboard handling.
React Hook Form: useForm(), Controller for TextInput wrapping, handleSubmit for validation. Validation: Zod or Yup schemas with resolver. Input types: TextInput with keyboardType (email-address, numeric, phone-pad), secureTextEntry for passwords. Keyboard handling: KeyboardAvoidingView or react-native-keyboard-aware-scroll-view. UX: autoFocus on first field, returnKeyType for 'next'/'done', ref-based focus management. Picker: @react-native-picker for dropdowns. Date: DateTimePicker. Error display: inline error messages below fields.
Use Jest for unit tests, React Native Testing Library for component tests, Detox for E2E, and manual testing on real devices.
Unit: Jest with mock for native modules (jest.mock('react-native')). Components: React Native Testing Library — render, fireEvent, waitFor. Testing Library philosophy: test behavior not implementation. Mocking: AsyncStorage, navigation, native modules. E2E: Detox (Wix, gray-box) — app runs on simulator/device, Maestro (YAML-based, simpler). Snapshot: Jest snapshot testing for component output. Coverage: istanbul via jest --coverage. CI: EAS, GitHub Actions with Detox. Real device testing: BrowserStack App Live. Performance: measure FPS drops, startup time in tests.
Use EAS Build for cloud builds, EAS Submit for store submission, follow review guidelines, and use OTA updates for JS changes.
Build: EAS Build (recommended), local Xcode/Gradle. Signing: iOS provisioning profiles and certificates, Android keystore. Stores: App Store Connect (iOS, 1-3 day review), Google Play Console (Android, hours-days review). Versioning: semver, buildNumber/versionCode auto-increment. Testing tracks: TestFlight (iOS), Internal Testing (Android). OTA updates: EAS Update or CodePush for JS-only changes without store review. CI/CD: GitHub Actions → EAS Build → EAS Submit. Monitoring: crash reporting, analytics, store ratings. Rejection handling: respond to review feedback, update guidelines compliance.
Pros: code sharing, fast iteration, large ecosystem. Cons: native performance gap, platform-specific bugs, dependency on bridge.
Pros: (1) 70-80% code sharing between iOS/Android. (2) JavaScript ecosystem and community. (3) Hot reloading for fast development. (4) OTA updates without store review. (5) Strong hiring pool (JS developers). (6) Good for content-heavy and CRUD apps. Cons: (1) Performance gap for complex animations/computations (improving with New Architecture). (2) Platform-specific bugs requiring native knowledge. (3) Large app size. (4) Upgrading React Native versions can be painful. (5) Native developer still needed for complex features. (6) Not ideal for graphics-intensive apps. Airbnb sunset RN but many companies (Meta, Microsoft, Shopify) continue investing.
Use Image/FastImage components, proper caching, responsive sizing, and optimize formats. Use expo-av for video/audio.
Image: require('./local.png') for bundled, {uri: 'https://...'} for remote. FastImage: caching, priority loading, preloading. Sizing: resizeMode (cover, contain, stretch). SVG: react-native-svg with SvgUri. Performance: compress images, use WebP, appropriate dimensions. Background: ImageBackground component. Caching: FastImage caches automatically, or manual with file system. Video: expo-av or react-native-video. Camera: expo-camera. Picker: expo-image-picker for gallery/camera selection. Upload: multipart/form-data with fetch or axios.
Hermes is Meta's JavaScript engine optimized for React Native, offering faster startup, lower memory usage, and smaller app size.
Hermes: compiles JS to bytecode at build time (no JIT). Benefits: (1) Faster startup (bytecode precompiled, no parse/compile at runtime). (2) Lower memory (optimized GC). (3) Smaller APK (bytecode smaller than minified JS). (4) Better performance on low-end devices. Enabled by default in React Native 0.70+. Debugging: Hermes-compatible Chrome DevTools via Flipper. Profiling: Hermes sampling profiler. Limitations: no eval() in production (bytecode only), some ES features may differ. Comparison: V8 (Chrome), JavaScriptCore (Safari) vs Hermes (RN-optimized).
Create a native module wrapper, link native SDK libraries, expose methods via bridge/TurboModules, and handle platform differences.
Steps: (1) Install SDK: CocoaPods (iOS), Gradle (Android). (2) Create native module: iOS (Swift/ObjC class extending RCTBridgeModule), Android (Kotlin/Java class extending ReactContextBaseJavaModule). (3) Expose methods: @objc func methodName(_ resolve: RCTPromiseResolveBlock) for iOS. @ReactMethod fun methodName(promise: Promise) for Android. (4) Register: in AppDelegate/MainApplication. (5) JS wrapper: NativeModules.MyModule.methodName(). Expo config plugin: automate native setup for managed workflow. Community: check if wrapper exists before building custom one. New Architecture: TurboModule spec → codegen.
Use HeadlessJS (Android), Background Fetch, task managers, and native modules for background processing and sync.
Android: HeadlessJS runs JS without UI. react-native-background-fetch: periodic background execution (minimum 15 min iOS). react-native-background-actions: long-running foreground service. Geolocation: react-native-background-geolocation for tracking. Push notifications: silent push triggers background processing. Expo: expo-task-manager + expo-background-fetch. iOS limitations: strict background execution limits (30 seconds), BGTaskScheduler for longer tasks. Offline sync: queue operations, process in background. Battery: minimize background activity, respect battery optimization settings. Testing: test on real devices (simulators don't behave same for background).
Ready to master React native?
Start learning with our comprehensive course and practice these questions.