React Native Senior Developer Interview Questions & Answers
This comprehensive guide covers essential topics for senior React Native developer interviews with practical examples and real-world analogies.
1. Performance Optimization
Question: How do you optimize FlatList performance for large datasets?
Analogy: Think of FlatList like a library reading room. Instead of displaying all books at once, you only show what's visible on the current shelf, and load the next shelf as the reader scrolls.
Key Optimization Techniques:
javascript
const OptimizedList = ({ data }) => {
const renderItem = useCallback(({ item }) => , []);
const keyExtractor = useCallback((item) => item.id.toString(), []);
return (
({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
})}
removeClippedSubviews={true}
maxToRenderPerBatch={10}
initialNumToRender={10}
windowSize={5}
/>
);
};
const ListItem = React.memo(({ item }) => (
{item.title}
));
Critical Points:
- Use
React.memoto prevent unnecessary re-renders - Implement
getItemLayoutfor fixed-height items (tells FlatList exact dimensions upfront) - Set
windowSize={5}to render 5 screens worth of content - Enable
removeClippedSubviewsto unmount off-screen items
2. Native Modules Integration
Question: How do you create and use a native module in React Native?
Analogy: Think of native modules as translators between two people who speak different languages. JavaScript speaks to the native code (iOS/Android) through this bridge, allowing access to platform-specific features.
iOS Implementation (Simplified):
objective-c
// RNBiometricAuth.m
#import "RNBiometricAuth.h"
#import
@implementation RNBiometricAuth
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(authenticate:(NSString *)reason
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
LAContext *context = [[LAContext alloc] init];
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:reason
reply:^(BOOL success, NSError *error) {
if (success) {
resolve(@{@"success": @YES});
} else {
reject(@"AUTH_FAILED", @"Authentication failed", error);
}
}];
}
@end
JavaScript Usage:
javascript
import { NativeModules } from 'react-native';
const { RNBiometricAuth } = NativeModules;
const authenticate = async () => {
try {
const result = await RNBiometricAuth.authenticate("Please authenticate");
return result.success;
} catch (error) {
return false;
}
};
Key Concepts:
- Use
RCT_EXPORT_MODULE()to expose module to JavaScript - Use
RCT_EXPORT_METHODfor async methods with Promise support - Native modules run on separate thread, perfect for heavy operations
3. State Management
Question: Compare Redux, MobX, and Zustand. When would you use each?
Analogy: Think of state management like organizing a company:
- Redux is like a corporate office with strict procedures and documentation
- Zustand is like a small startup with minimal bureaucracy
- Context API is like a family business - simple and direct
javascript
import create from 'zustand';
const useStore = create((set) => ({
user: null,
loading: false,
fetchUser: async (userId) => {
set({ loading: true });
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
set({ user: data, loading: false });
},
updateUser: (updates) => set((state) => ({
user: { ...state.user, ...updates }
})),
}));
// Usage
const UserProfile = () => {
const { user, fetchUser } = useStore();
useEffect(() => { fetchUser('123'); }, []);
return {user?.name} ;
};
Redux Toolkit (For large enterprise apps):
javascript
const userSlice = createSlice({
name: 'user',
initialState: { data: null, loading: false },
reducers: {
updateUser: (state, action) => {
state.data = { ...state.data, ...action.payload };
},
},
});
When to Use:
- Redux: 50+ screens, time-travel debugging, strict team structure
- Zustand: Most apps (10-50 screens), simple API, great performance
- Context API: Small apps (<10 screens), theme/auth only
4. Navigation Architecture
Question: How do you implement deep linking with React Navigation?
Analogy: Think of deep linking like giving someone directions to a specific room in a building. Instead of saying "go to the building," you say "go to Building A, 3rd floor, Room 305" - they land exactly where they need to be.
Simple Deep Linking Setup:
javascript
import { NavigationContainer } from '@react-navigation/native';
const linking = {
prefixes: ['myapp://', 'https://myapp.com'],
config: {
screens: {
Home: '',
Profile: 'profile/:userId',
Article: 'article/:id',
Settings: 'settings',
},
},
};
function App() {
return (
);
}
How it works:
- URL
myapp://profile/123automatically navigates to ProfileScreen with userId=123 - Works with both custom schemes (
myapp://) and universal links (https://myapp.com) - Configure in iOS
Info.plistand AndroidAndroidManifest.xml
5. Testing Strategies
Question: How do you write effective tests for React Native components?
Analogy: Testing is like having a safety net for circus performers. Unit tests catch small mistakes (individual tricks), integration tests catch coordination issues (routines), and E2E tests ensure the whole show works.
Essential Test Structure:
javascript
import { render, fireEvent, waitFor } from '@testing-library/react-native';
describe('UserProfile', () => {
it('renders user data after loading', async () => {
const { getByText, getByTestId } = render( );
// 1. Check loading state
expect(getByTestId('loading-spinner')).toBeTruthy();
// 2. Wait for async data
await waitFor(() => {
expect(getByText('John Doe')).toBeTruthy();
});
});
it('handles button press correctly', () => {
const onPress = jest.fn();
const { getByText } = render();
fireEvent.press(getByText('Click'));
expect(onPress).toHaveBeenCalled();
});
});
Testing Priorities:
- Unit Tests: Test pure functions and utility logic
- Component Tests: Test user interactions (button press, form input)
- Integration Tests: Test component communication
- E2E Tests: Test critical user flows (login, checkout)
6. Code Splitting & Lazy Loading
Question: How do you implement code splitting in React Native?
Analogy: Think of code splitting like streaming a movie vs downloading it entirely first. You load what you need now, and download the rest when required - faster initial load, better user experience.
Lazy Loading Components:
javascript
import React, { Suspense, lazy, useState } from 'react';
import { View, ActivityIndicator } from 'react-native';
// Lazy load heavy components
const HeavyChart = lazy(() => import('./HeavyChart'));
const DashboardScreen = () => {
const [showChart, setShowChart] = useState(false);
return (
);
};
Metro Config Optimization:
javascript
// metro.config.js
module.exports = {
transformer: {
getTransformOptions: async () => ({
transform: {
inlineRequires: true, // Loads modules only when needed
},
}),
},
};
Impact: Can reduce initial bundle size by 30-40% for large apps
7. Memory Management
Question: How do you prevent memory leaks in React Native?
Analogy: Memory leaks are like leaving the faucet running. Each unmounted component that doesn't clean up leaves a drip - eventually you flood the system. Always turn off the tap (cleanup) when leaving.
Essential Cleanup Pattern:
javascript
import { useEffect, useRef } from 'react';
const UserComponent = () => {
const isMounted = useRef(true);
useEffect(() => {
isMounted.current = true;
// Cleanup when component unmounts
return () => {
isMounted.current = false;
};
}, []);
// Safe async operation
const fetchData = async () => {
const response = await fetch('/api/data');
const data = await response.json();
// Only update if component still mounted
if (isMounted.current) {
setData(data);
}
};
// Cleanup event listeners
useEffect(() => {
const subscription = EventEmitter.addListener('update', handleUpdate);
return () => {
subscription.remove(); // Critical: Always cleanup
};
}, []);
return ... ;
};
Common Memory Leak Sources:
- Event Listeners: Always call
.remove()in cleanup - Timers: Clear all
setTimeout/setInterval - Async Operations: Check
isMountedbefore setState - Native Modules: Release native resources in cleanup
Key Takeaways
Performance First
- Optimize FlatList with memoization and windowing
- Lazy load heavy components to reduce bundle size
- Understand native module bridges for iOS and Android
- Know when to drop down to native code
- Choose tools based on app size (Context < Zustand < Redux)
- Keep state close to where it's used
- Write tests for critical user flows
- Always cleanup subscriptions and listeners
- Implement proper error boundaries
Final Thoughts
Senior React Native positions require more than just coding skills. You need to understand:
- Why certain patterns exist, not just how to use them
- When to optimize vs when premature optimization hurts
- How to balance native power with cross-platform benefits
Frequently Asked Questions (FAQ)
Q: How do I prepare for senior React Native interviews?
Focus on: 1) FlatList performance optimization (60% of performance questions), 2) Bridge understanding (JS ↔ Native communication), 3) State management at scale (Context API vs Redux vs Zustand), 4) Build sample app with: pagination, image caching, offline support, 5) Know when React Native is wrong choice (games, AR/VR, heavy animations), 6) Practice system design (design WhatsApp, Instagram with RN), 7) Review Hermes, JSI, and Fabric (new architecture).
Q: Should I learn native iOS/Android for senior React Native roles?
Yes, understanding is crucial (not mastery). Know: 1) iOS: Swift basics, CocoaPods, Xcode project structure, AppDelegate, Info.plist, 2) Android: Kotlin basics, Gradle, AndroidManifest, MainActivity, 3) How to write native modules (80% of senior roles need this), 4) Debugging native crashes (symbolication, Xcode debugger, Android Studio logcat), 5) When to use native vs JavaScript (camera, Bluetooth, background tasks favor native).
Q: What's the difference between Expo and bare React Native workflow?
Expo (managed): Pre-configured, over-the-air updates, easier setup, limited to Expo SDK (no custom native modules). Bare workflow: Full native access, any native module, custom native code, requires Xcode/Android Studio. Senior roles expect: knowledge of when to use each (Expo for MVPs/simple apps, bare for complex apps), how to migrate Expo → bare, and experience with both. Most production apps use bare workflow.
Q: How do I explain React Native performance bottlenecks in interviews?
Use this framework: 1) Identify bottleneck type (JS thread, UI thread, or bridge), 2) JS thread: Heavy computations, large state updates → Solution: useMemo, lazy loading, worker threads, 3) UI thread: Complex layouts, shadows, blur → Solution: shouldComponentUpdate, FlatList optimization, 4) Bridge: Frequent JS ↔ Native calls → Solution: batching, JSI (synchronous calls), 5) Always mention profiling first (React DevTools Profiler, Flipper).
Q: What are red flags that make React Native the wrong choice?
Avoid React Native for: 1) Real-time games (Unity/Unreal better), 2) AR/VR apps (native ARKit/ARCore required), 3) Apps with 50+ complex animations (native performs better), 4) Apps requiring background execution (geolocation tracking, music players - native easier), 5) Apps needing newest OS features immediately (native gets APIs first, RN waits 3-6 months). Demonstrate you know trade-offs, not just RN evangelism.
Q: How do I handle "Why React Native over Flutter?" in interviews?
Balanced answer showing maturity: Choose React Native when: 1) Team knows JavaScript/React (retraining cost), 2) Large npm ecosystem needed (400K+ packages), 3) Need to share code with React web app, 4) Mature ecosystem (2015 vs Flutter 2017). Choose Flutter when: Better performance needed (closer to native), simpler state management (Provider), single company backing (Google vs Facebook/Meta + community). Senior answer: "Both are great, choice depends on team and requirements."
Q: What salary should I expect for senior React Native roles in 2025?
US market: $120K-180K (SF/NYC: $150K-200K). Europe: €55K-85K (€70K-110K London). Remote: $100K-140K. Factors: Years with React Native (3+ for senior), native module experience (+15-25%), published apps with 100K+ users, contributions to React Native core or popular libraries, full-stack capabilities (Node.js backend +10-15%), system design expertise. React Native developers typically earn 10-15% less than native iOS/Android but have 2X job opportunities.

Ali Mert Güleç
Mobil Odaklı Full Stack Mühendis
7+ yıllık iOS, Android ve React Native geliştirme uzmanlığı ile olağanüstü mobil deneyimler yaratmaya tutkulu. Dünya çapında işletmelerin fikirlerini milyonlarca aktif kullanıcıya sahip başarılı uygulamalara dönüştürmelerine yardımcı oldum.