This guide is part of a 719-question React Native interview handbook collected from real interviews across startups, product companies, fintech, e-commerce, and MNCs. Questions range from beginner to senior (5+ years) and cover JavaScript, React Native, New Architecture, performance, security, native modules, iOS, Android, system design, and behavioral interviews.
This article contains 200 questions (global questions 221–420). Answer each question before reading the response, explain assumptions and complexity for coding questions, and adapt behavioral examples to your truthful experience.
Difficulty guide
- 🟢 Beginner — expected for entry-level and junior React Native roles.
- 🟡 Intermediate — expected for engineers who can independently ship features.
- 🔴 Senior — tests architecture, trade-offs, production ownership, and native-platform knowledge.
Topics in this part
- React Native Basics — questions 74–124
- Components, layout, navigation, and state management
- APIs, networking, and offline storage
- Performance, profiling, native modules, Fabric, TurboModules, and JSI
- Native Android and iOS integrations
- Animations and push notifications
Complete series
This Dev.to series has five core handbook articles plus five focused practice extras. Open the series page to move through the complete reading order:
- Part 1: JavaScript — core handbook, questions 1–120
- Part 2: React — core handbook, questions 121–220
- Part 3: React Native — core handbook, questions 221–420
- Part 4: Performance & Architecture — core handbook, questions 421–560
- Part 5: Senior & System Design — core handbook, questions 561–719
- Part 6: Output-Based JavaScript Practice — bonus practice article
- Part 7: Coding Interview Practice — bonus practice article
- Part 8: Code Output Challenges — bonus practice article
- Part 9: Current React Native Interview Questions — new high-frequency practice article
- Part 10: Project & Production Interviews — senior project ownership and real-production practice
Series navigation
Use the Complete React Native Interview Handbook 2026 series page on Dev.to to open every part in order.
Practical coding interview tasks
Interviewers evaluate reasoning, accessibility, error handling, and testability—not only the first working implementation.
🟡 Build an OTP screen
Build a six-digit OTP screen with accessible inputs, paste handling, a resend cooldown, loading and error states, and timer cleanup. Explain how you prevent duplicate verification requests.
🟡 Optimize a slow FlatList
Determine whether the JavaScript thread, UI thread, image decoding, or network is responsible. Improve row rendering, stable keys, image sizing, getItemLayout when appropriate, and virtualization settings; then re-measure in a release build.
🟡 Explain why a component re-renders
Use the React Profiler to identify whether props, state, context, or a parent render caused the work. Propose the smallest correction before adding memoization.
🟡 Write a custom hook
Create useDebouncedSearch(query) that debounces requests, aborts obsolete work, ignores stale responses, exposes loading/error states, and cleans up on unmount.
🔴 Implement protected deep linking
Parse and validate an incoming URL, wait for authentication hydration, queue protected destinations through login, and handle cold starts, warm links, and malformed URLs.
🔴 Create a TurboModule
Define a typed Codegen spec, implement the generated Android and iOS contracts, expose Promises for one-shot work and events for streams, document thread ownership, and test errors on both platforms.
Architecture diagrams
React Native New Architecture
React components
│ reconciliation
▼
Fabric renderer ─────────────► Native views on the UI thread
│
├── Yoga layout
▼
JSI ◄──────── Codegen typed contracts ───────► TurboModules
│ │
▼ ▼
Hermes JavaScript runtime Kotlin / Swift / C++
Fabric rendering flow
React state update → React reconciliation → Fabric shadow tree → Yoga layout
│
▼
Mount instructions → Native view commit
JavaScript thread versus UI thread
JavaScript thread UI / main thread
───────────────── ────────────────
React render and state Touch input
Business logic Native view mounting
Network callbacks Drawing and compositing
Most event handlers Platform animations
Long synchronous JavaScript work delays handlers and JS-driven updates. Blocking native work can cause dropped frames or Android ANRs.
Continuation note
This part continues React Native Basics from Part 2 before completing the core platform and New Architecture topics.
Question bank
74. Feature flags in a large app?
Answer
Answer: I define typed flags with safe defaults, fetch remote values after startup, cache them, and expose them through a focused hook or store. Critical flags should be evaluated server-side too. I support gradual rollout, user targeting, analytics, and cleanup dates so old flags do not become permanent branches. Firebase Remote Config is a common implementation.
75. Guidelines you follow while writing code?
Answer
Answer: I optimize for readability, small typed interfaces, single responsibility, predictable state, immutable updates, explicit error/loading states, cleanup of resources, accessibility, security, testability, and observability. I avoid premature abstraction and optimize only measured paths. PRs are small, names explain intent, and comments explain why rather than restating code.
76. Heavy third-party libraries slow the app — what do you do?
Answer
Answer: I inspect bundle and native binary contributions, usage coverage, startup side effects, and alternatives. I import narrow entry points when tree shaking works, replace large general libraries with focused utilities, lazy-initialize SDKs, remove duplicate versions, and avoid importing locales/assets. For native SDKs I verify ABI size and strip unused architectures. I measure before and after.
77. How do TurboModules differ from legacy native modules?
Answer
Answer: TurboModules use JSI, Codegen-typed contracts, and lazy initialization rather than Bridge registration and serialized calls. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
78. How do deep links and universal/app links stay secure?
Answer
Answer: Verify domains, allowlist and parse routes, pass protected destinations through auth and permission checks, validate expiring links on the server, and constrain redirects.
79. How do feature flags differ from remote config?
Answer
Answer: Remote config distributes values; feature management adds targeting, rollout, experimentation, audit, and lifecycle. Flags need safe defaults, owners, expiry, exposure telemetry, and server-compatible semantics.
80. How do microtasks affect responsiveness on the React Native JavaScript thread?
Answer
Answer: Promise and await continuations run through the runtime's microtask processing, and a long self-perpetuating microtask chain can delay timers, input handling, and React work even though each callback is asynchronous. I avoid unbounded chains, yield deliberately when appropriate, and profile long JavaScript tasks on the target engine.
81. How do preventExtensions(), seal(), and freeze() differ?
Answer
Answer: preventExtensions blocks new properties; seal also blocks deletion and reconfiguration; freeze additionally makes existing data properties non-writable. All are shallow.
82. How do you debug Hermes?
Answer
Answer: Attach React Native DevTools or compatible tooling, use source maps for JavaScript stacks, the Hermes sampling profiler for CPU work, and symbolicate release crashes with matching artifacts.
83. How do you decide between Expo and the React Native Community CLI?
Answer
Answer: Compare native SDK and build needs, update policy, team expertise, and operations. Expo supports custom native code and development builds; Community CLI can suit direct native infrastructure.
84. How do you design secure authentication with refresh, biometrics, and session expiry?
Answer
Answer: Keep short-lived access tokens in memory, protect refresh tokens with Keychain or Keystore, single-flight refresh on eligible 401s, gate credential access with biometrics, revoke on logout, and enforce idle expiry.
85. How do you design the best scalable React Native architecture?
Answer
Answer: I use feature-first modules containing screen, components, hooks, domain logic, and API. Shared layers include design system, navigation, networking, storage, analytics, and native adapters. Dependencies point inward toward domain interfaces. I separate server state from client state, add typed errors, testing seams, feature flags, monitoring, and CI. The architecture should be proportional to app and team size, not ceremony for its own sake.
86. How do you ensure consistency when syncing large datasets on unreliable networks?
Answer
Answer: I use incremental cursors rather than full downloads, database transactions, version numbers or updatedAt fields, idempotent mutations, and checkpointed batches. Conflicts need an explicit policy such as server-wins, last-write-wins, or field-level merge. I verify checksums/counts, resume after failure, and never mark a batch synced until the local transaction commits.
87. How do you expose Kotlin code to React Native?
Answer
Answer: Implement the generated TurboModule or legacy ReactContextBaseJavaModule contract, expose methods, package the module, and register or autolink it.
88. How do you expose Swift code to React Native?
Answer
Answer: Add the native dependency, implement the generated or legacy module interface, bridge Swift through Objective-C or Objective-C++ where needed, and register it.
89. How do you handle expensive computation that blocks the JavaScript thread?
Answer
Answer: Chunk interruptible work, defer noncritical tasks, move justified compute to a threaded native or C++ module, and keep UI math in worklets.
90. How do you handle multithreading in React Native?
Answer
Answer: JavaScript app logic normally runs on one JS thread. Native SDKs can perform work on background queues; Reanimated worklets run on the UI runtime; libraries can provide worker threads or JSI runtimes. I never update UI from arbitrary native threads. For CPU-heavy work I choose native background execution or chunking, with cancellation, lifecycle, and message-size considerations.
91. How do you integrate a third-party native SDK?
Answer
Answer: Install with Gradle, CocoaPods, or SPM; configure platform permissions and lifecycle; wrap the SDK behind a narrow typed adapter; and test release builds.
92. How do you investigate random unreproducible crashes?
Answer
Answer: Use symbolicated Sentry or Crashlytics groups, breadcrumbs, release and device filters, matching source maps and native symbols, and bisect recent native or engine changes.
93. How do you keep animations smooth under JS load?
Answer
Answer: Keep frame-by-frame gesture and animation work in UI-runtime worklets or native-driven primitives, minimize layout-heavy properties and cross-runtime values, and profile under realistic concurrent activity.
94. How do you make accessibility part of architecture?
Answer
Answer: Build roles, labels, states, hit targets, contrast, font scaling, focus, and reduced motion into design-system primitives; test critical flows manually with VoiceOver and TalkBack.
95. How do you optimize React Native runtime performance?
Answer
Answer: Profile JS/UI FPS and hot renders, virtualize large lists, use stable keys, reduce unnecessary renders and bridge traffic, clean subscriptions, and split or move heavy synchronous work. Memoize only measured hot paths.
96. How do you optimize a large feed?
Answer
Answer: Use cursor pagination, stable keys, small rows, sized cached images, and virtualization. Apply fixed layouts and meaningful memoization, then tune windows and batches against blanks and memory.
97. How do you plan a risky React Native upgrade?
Answer
Answer: Read release and Upgrade Helper changes, map dependencies, separate mechanical work from features, baseline quality and performance, test clean and upgrade paths, canary by version, and preserve rollback.
98. How do you prevent TextInput from being hidden by the keyboard on Android?
Answer
Answer: Use correct insets, KeyboardAvoidingView or a keyboard controller, verify adjustResize, and test edge-to-edge behavior with gesture navigation.
99. How do you prevent expensive re-renders?
Answer
Answer: I move state close to consumers, split Contexts, select narrow store slices, preserve immutable references, memoize measured expensive computations, use React.memo for stable child props, and avoid recreating configuration objects in hot lists. React Profiler confirms whether render time actually improves. Sometimes virtualization or reducing work inside render matters more than skipping renders.
100. How do you prevent stale or out-of-order search responses?
Answer
Answer: Debounce for volume, but use AbortController or a latest request ID for correctness. Apply a response only when it still matches the active query.
101. How do you secure APIs from a mobile app?
Answer
Answer: I use HTTPS, short-lived tokens, refresh rotation, server-side authorization, request validation, rate limiting, and optional device/app attestation. The app never holds server secrets. Sensitive operations can use a nonce, timestamp, or HMAC generated with a device-bound key, but HMAC is only useful if that key is protected and the server prevents replay. Client checks complement, not replace, backend security.
102. How do you secure secrets and authentication data?
Answer
Answer: Treat the client as untrusted: backend service secrets stay server-side; public keys are restricted; tokens use short lifetimes, rotation, revocation, and platform secure storage; logs avoid PII.
103. How do you structure a scalable React Native app?
Answer
Answer: I prefer feature-based folders: each feature has screens, hooks, components, and API. Shared design system, navigation, and services stay at the top. Client state and server state are separated. I add Error Boundaries per major tab, strong TypeScript, Sentry early, Hermes on, and CI for lint/test/release. Architecture should match team size — not over-engineer a small app.
104. How should exponential-backoff retries be designed?
Answer
Answer: Use bounded attempts, exponential delays with jitter and a maximum cap, honor server retry hints, and retry only transient and safe/idempotent operations.
105. Offline users create conflicting edits that sync later?
Answer
Answer: I give every mutation an idempotency key, local timestamp/version, and durable queue entry. The backend returns authoritative versions. On conflict I apply the product's policy—server wins, last write wins, field merge, or user resolution—inside a transaction. I show pending/conflict state in UI and never silently discard local changes.
106. Service workers and how they relate to React Native?
Answer
Answer: Service workers are browser background scripts for caching, offline web apps, and push. They apply to React web/PWAs, not standard native React Native apps. React Native uses native background tasks, FCM/APNs, local databases, and OS schedulers instead. React Native Web may use service workers when deployed as a web app.
107. The Android app shows ANRs but no crashes?
Answer
Answer: An Android ANR means the main thread failed to respond within a system-defined timeout for an input, component, or broadcast operation. I start with Play Console Android vitals or captured ANR traces, inspect the blocked main-thread stack and locks, and correlate it with Perfetto or system traces. StrictMode can expose accidental disk or network work during development, but it does not replace ANR traces and should not be described as the ANR detector. I move blocking work off the main thread, shorten lock scope, and verify the affected path on a release build.
108. What are Symbols used for?
Example:Answer
Answer: Symbols are unique property keys that avoid name collisions. Well-known symbols such as Symbol.iterator let objects customize language behavior.
const id = Symbol('id');
obj[id] = 123;
109. What are async generators?
Example:Answer
Answer: An async generator can await work and yield asynchronous values. Consumers use for await...of, which is useful for paginated or streaming data.
async function* pages() {
yield await fetchPage(1);
}
110. What changed recently in React Native 0.82 through 0.86?
Answer
Answer: 0.82 became New-Architecture-only; 0.83 expanded DevTools network and performance tooling; 0.84 defaulted Hermes V1 and precompiled iOS binaries; 0.85 changed animation and Jest packaging; 0.86 expanded Android edge-to-edge and DevTools.
111. What happens after process death, app upgrade, logout, or token expiry?
Answer
Answer: Durable state must rehydrate safely, migrations must be versioned, in-flight work must be replay-safe or discarded, logout must clear identity-bound state, and expiry must enter controlled refresh or sign-out.
112. What is C++ used for in React Native?
Answer
Answer: C++ provides shared cross-platform infrastructure for JSI, Fabric shadow nodes, Yoga, TurboModule bindings, and Hermes integration.
113. What is Hermes V1, and how do you evaluate its benefit?
Answer
Answer: Hermes V1 became the default in RN 0.84. I compare cold start, interactive time, memory, bundle load, long tasks, and interaction latency in representative release builds.
114. What is the rollback plan if the rollout metric regresses?
Answer
Answer: I define stop thresholds, staged cohorts, artifact or OTA rollback, feature-disable controls, ownership, and communication before release, then verify data and database compatibility with rollback.
115. What is useEffectEvent, and how does it help avoid stale effect logic?
Example:Answer
Answer: useEffectEvent creates logic that always reads the latest props and state without making the surrounding effect resubscribe whenever those values change. It is useful for non-reactive event logic called from an effect. It must not be used to hide dependencies that should genuinely rerun the effect. In React Native, availability follows the React version bundled by the chosen React Native release, so I verify that toolchain before using the API.
const onConnected = useEffectEvent(() => showToast(theme));
useEffect(() => connect(roomId, onConnected), [roomId]);
116. What platform differences should a senior React Native engineer know?
Answer
Answer: Expect differences in back and navigation gestures, keyboard and insets, permissions, background execution, push, files, fonts, shadows, accessibility, and lifecycle. Android edge-to-edge requires explicit inset handling.
117. What steps do you take before publishing to production?
Answer
Answer: Test signed release builds on real devices; verify crash reporting, mappings, permissions, links, push, versions, privacy disclosures, performance, analytics, and environment configuration.
118. When is React Native the wrong choice?
Answer
Answer: It may not fit graphics-heavy games, deeply platform-specific products, hard realtime native-dominated pipelines, or a single-platform team with no sharing benefit.
119. Which React 19 features are web-specific rather than React Native features?
Answer
Answer: React core features such as Actions, useActionState, useOptimistic, use, ref as a prop, and context shorthand may apply when the React Native renderer supports the required React version. React DOM features such as native form Actions, useFormStatus, document metadata, stylesheet precedence, resource preloading, and custom-element improvements target the web. A senior answer separates React core capability from renderer-specific support. In React Native, availability follows the React version bundled by the chosen React Native release, so I verify that toolchain before using the API.
120. Which metric proves the optimization helped real users?
Answer
Answer: Use a user-centered latency or success metric segmented by representative cohort, with guardrails for crashes, memory, and correctness, and compare before and after under equivalent releases.
121. Which production signals do you monitor?
Answer
Answer: Monitor crash-free users, ANRs, JS and native errors, startup and screen-ready latency, long tasks, frame health, memory, network success, and app size, segmented by release and cohort.
122. Which work runs on the JavaScript thread and which runs on the UI/main thread?
Answer
Answer: React and most app logic run in JavaScript; input, native layout commits, and drawing use the main thread; UI-runtime worklets may run separately. I trace the implementation rather than assuming.
123. Why do push notifications work in foreground but not when the app is terminated?
Answer
Answer: Verify APNs or FCM credentials, entitlements, payload type, native killed-state handlers, Android channels and OEM restrictions, and test the signed release build.
124. iOS SDK integration for folder/framework/xcframework or Git URL?
Answer
Answer: For XCFramework/framework I add it through CocoaPods vendored_frameworks or Xcode, set Embed & Sign for dynamic frameworks, link required system frameworks, and verify simulator/device slices. For source folders I create a podspec with source_files and dependencies. For GitHub/GitLab I prefer a tagged CocoaPod or Swift Package URL. Then I add permissions, capabilities, initialization, an Obj-C++/Swift RN wrapper, and test archive—not only simulator.
Components & Lifecycle
8 reviewed questions.
🟡 Intermediate
1. A component continues updating after the user leaves the screen?
Answer
Answer: I inspect timers, subscriptions, native event emitters, sockets, and unresolved requests. Every effect must return symmetric cleanup: clear timers, remove listeners, close sockets, and abort requests. If navigation keeps the screen mounted, I use focus/blur lifecycle deliberately rather than assuming unmount. I also remove obsolete isMounted flags when proper cancellation is available.
2. AppState and background tasks?
Answer
Answer: AppState reports active, background, or inactive transitions. I use it to pause timers, refresh stale data, lock sensitive screens, and record session state. Background execution is OS-limited: iOS requires approved background modes and Android may use WorkManager or foreground services. Libraries such as Expo TaskManager or background-fetch wrap these native mechanisms.
3. Cancel async on unmount?
Answer
Answer: Create cancellable work inside the effect and cancel it in cleanup, for example with AbortController or the subscription API returned by a native module. Guard result application when an operation cannot be cancelled so an obsolete request cannot update the screen.
4. Class component vs function component?
Answer
Answer: Class components use this, instance state, and lifecycle methods. Function components use hooks and closures. Functions are now preferred because logic is easier to compose through custom hooks and there is less boilerplate. Classes are still relevant for legacy code and Error Boundaries, because standard hooks do not directly replace componentDidCatch.
5. Class lifecycle compared with hooks?
Answer
Answer: constructor initializes state; componentDidMount maps to an effect with empty dependencies; componentDidUpdate maps to an effect with dependencies; componentWillUnmount maps to the effect cleanup. shouldComponentUpdate maps conceptually to React.memo and careful state design. Hooks group related logic by feature instead of splitting it across lifecycle methods.
6. What happens internally when you render a component?
Answer
Answer: React calls the component, Fiber reconciles the new elements with the previous tree, the React Native renderer prepares host updates, Yoga computes layout, and the UI thread commits and paints.
🔴 Senior
7. What is a native UI component?
Answer
Answer: It is a platform view such as a map or camera exposed as a React Native host component, with typed props and events.
8. When would you build a TurboModule or native component?
Answer
Answer: Build a module for missing APIs, native SDKs, background integration, or measured compute needs; build a component for a platform view. Define a narrow typed contract, ownership, threading, errors, cancellation, and lifecycle. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
Styling & Layout (Flexbox)
6 reviewed questions.
🟡 Intermediate
1. Explain Flexbox in React Native?
Answer
Answer: React Native uses Yoga Flexbox and defaults flexDirection to column, unlike the web's row. justifyContent aligns on the main axis and alignItems on the cross axis. flex:1 means the view grows to fill available space, with shrink behavior determined by the platform/style. I avoid hardcoded dimensions when Flexbox can express the layout.
2. How does Flexbox behavior in React Native differ from CSS on the web?
Answer
Answer: React Native uses Yoga for Flexbox-like layout with a default flexDirection of column and a JavaScript style API rather than browser CSS. Not every web property or measurement behavior exists, text has platform-specific layout rules, and absolute positioning still participates in a native layout pass. I verify edge cases on both platforms rather than assuming browser behavior.
3. StyleSheet.create vs normal style object?
Answer
Answer: Both ultimately describe native styles. StyleSheet.create centralizes styles, validates keys in development, and provides stable references when declared outside render. Inline objects are useful for truly dynamic values but create new references each render. I keep static styles in StyleSheet and combine them with small dynamic arrays.
🔴 Senior
4. How do you achieve responsive design?
Answer
Answer: I use Flexbox, safe-area insets, percentage or measured widths, useWindowDimensions for live orientation changes, scalable typography, and platform-aware spacing. I test small phones, tablets, font scaling, RTL, and landscape. I avoid one-time Dimensions.get values when the layout must react to rotation.
5. How do you design responsive layouts with safe areas and keyboard insets?
Answer
Answer: Build from flexible constraints, use current window dimensions when behavior truly depends on available size, and consume safe-area and keyboard insets at the owning screen boundary. Avoid one-time global dimensions and hard-coded device offsets. Test rotation, split-screen, large text, notches, edge-to-edge Android, and external keyboards.
6. Responsive UI vs response UI?
Answer
Answer: If the interviewer means responsive UI, I explain layouts adapting to device size, orientation, insets, and font scaling. If they mean response-driven UI, I explain explicit loading, skeleton, empty, error, retry, offline, and success states for API responses. I clarify ambiguous wording before answering rather than guessing.
Navigation
8 reviewed questions.
🟢 Beginner
1. What is React Navigation?
Answer
Answer: React Navigation is a common JavaScript navigation library providing stacks, tabs, drawers, linking, and navigation state for React Native.
2. navigate vs replace vs goBack?
Answer
Answer: navigate goes to a screen and keeps history. replace swaps the current screen so the user cannot go back to it — useful after login. goBack pops the previous screen. After successful login I usually reset or replace so the login screen is not in the stack.
🟡 Intermediate
3. A screen makes the same API call three times after navigation. How do you investigate?
Answer
Answer: I first check React Strict Mode double effects in development. Then I inspect useEffect dependencies for new objects or callbacks, screen remounting, focus listeners registered without cleanup, and query-library refetch policies. I abort previous requests, make the effect dependencies stable, and choose either mount-based or focus-based fetching—not both accidentally.
4. How do Stack, Native Stack, Drawer, and Tabs differ?
Answer
Answer: A JS Stack offers flexible JavaScript transitions; Native Stack uses platform controllers for native transitions; Drawer provides a side menu; Tabs switch top-level destinations.
5. How do you persist navigation state?
Answer
Answer: Serialize navigation state on change and restore a compatible version at startup from storage.
6. How do you reset the navigation stack?
Example:Answer
Answer: Use navigation.reset or CommonActions.reset to replace route history, such as leaving only Home after login.
navigation.reset({ index: 0, routes: [{ name: 'Home' }] });
7. Senior navigation scenarios?
Answer
Answer: For logout I reset the root stack so protected screens cannot be revisited. For a deep link received before auth hydration, I queue it and navigate after session restoration. For duplicate screens I decide whether navigate, push, replace, or reset matches the UX. I persist navigation state only when needed and version it because stale routes can break after releases.
🔴 Senior
8. Explain React Navigation architecture and common navigators?
Answer
Answer: NavigationContainer owns navigation state and linking. Stack models push/pop screens, native stack uses platform-native transitions, tabs switch major areas, and drawer provides side navigation. I usually nest a stack inside each tab and keep auth and app flows in separate root groups. Params should contain small serializable identifiers, not large objects.
State Management
17 reviewed questions.
🟡 Intermediate
1. Complete Redux flow?
Answer
Answer: A component dispatches an action. Middleware can observe, transform, delay, or perform async work. The root reducer calls slice reducers with the previous state and action, reducers return the next immutable state, the store notifies subscribers, selectors derive data, and React-Redux re-renders components whose selected value changed. This one-way flow makes changes traceable.
2. Context API vs Redux — when should you use each?
Answer
Answer: Context distributes a value through the tree and fits low-frequency dependencies such as theme, locale, or a small auth object. When the provider value changes, consumers re-render. Redux provides normalized global state, selectors, middleware, predictable actions, and DevTools, so it fits complex workflows and frequent updates. I avoid using one giant Context as a Redux replacement.
3. How does MobX compare with Redux?
Answer
Answer: MobX uses observables and reactions around mutable-looking state; Redux uses explicit immutable event transitions.
4. How does Recoil compare with Redux?
Answer
Answer: Recoil models shared state as atoms and derived selectors, but Meta archived its repository in January 2025, so it is not a prudent default for new production work. I would first separate client state from server state, then consider maintained options such as Redux Toolkit, Zustand, or TanStack Query based on the ownership and consistency requirements. Existing Recoil applications need an explicit maintenance or migration plan rather than an assumption of active upstream support.
5. How does Zustand compare with Redux?
Answer
Answer: Zustand offers small hook-based stores with little boilerplate; Redux offers stricter event conventions, middleware, and mature team tooling.
6. Old Redux vs Redux Toolkit?
Answer
Answer: Classic Redux required action constants, action creators, switch reducers, manual immutable updates, and store setup. Redux Toolkit is the official modern approach: configureStore, createSlice, Immer-powered reducer syntax, built-in thunk, and sensible middleware. RTK Query adds server-state fetching and caching. I choose RTK for all new Redux code.
7. Reducers and scenario-based Redux questions?
Answer
Answer: Reducers must be deterministic and free of API calls, timers, storage, and mutation. For a cart I keep items normalized by id and derive totals with selectors rather than storing duplicate totals. For logout I reset sensitive slices centrally. For a list API I prefer RTK Query instead of hand-writing loading flags in reducers unless custom workflow requires it.
8. Redux persistence?
Answer
Answer: redux-persist saves selected slices to storage and rehydrates them on launch. I whitelist only safe, necessary data, version the persisted schema, write migrations, and never persist raw secrets in AsyncStorage. Loading must wait for or tolerate rehydration. Server cache and transient UI state usually should not be persisted blindly.
9. Redux updates cause the whole app to re-render?
Answer
Answer: I inspect selectors and Provider value rather than blaming Redux itself. Components should select the smallest stable slice, normalized entities should preserve unchanged references, and derived arrays should use memoized selectors. I split large components and avoid returning a new object from useSelector on every store update unless an equality function or memoized selector guarantees stability.
10. Redux vs Context vs Zustand / React Query?
Answer
Answer: Context is good for low-frequency global values like theme or auth user, but can over-render if the value changes often. Redux Toolkit is strong for complex client state with middleware and DevTools. Zustand is lighter for simple global stores. For server data — lists from APIs — I prefer TanStack Query because caching, retries, and loading states are solved for me. Companies like hearing: client state vs server state separation.
11. What is Redux Thunk?
Answer
Answer: Thunk allows dispatching functions that receive dispatch and getState, making straightforward asynchronous flows easy to express.
12. What is Redux Toolkit?
Answer
Answer: Redux Toolkit provides standard Redux patterns with createSlice, Immer-backed reducers, sensible defaults, and RTK Query.
13. What is Redux middleware?
Answer
Answer: Middleware runs between dispatch and reducers to implement logging, analytics, asynchronous flows, or policy around actions.
14. When do you use Redux versus Context?
Answer
Answer: Context suits low-frequency scoped dependencies such as theme. Redux suits complex shared state requiring explicit events, selectors, middleware, conventions, and DevTools.
🔴 Senior
15. Context, Redux Toolkit, Zustand, or TanStack Query—how do you choose?
Answer
Answer: Separate server from client state. Query tools own remote cache and invalidation; Context suits scoped low-frequency dependencies; Zustand suits small ergonomic stores; Redux Toolkit suits large teams needing explicit events and tooling.
16. How does Redux work under the hood?
Answer
Answer: createStore holds a current state and listener list. dispatch validates the action, invokes the root reducer with current state and action, replaces the state, then notifies listeners. React-Redux uses Context to provide the store and subscriptions/selectors to update only relevant components. Middleware wraps dispatch through function composition.
17. What is Redux Saga?
Answer
Answer: Saga uses generator effects to model cancellable workflows, races, and complex side effects.
APIs & Networking
23 reviewed questions.
🟢 Beginner
1. How do you call an API in React Native?
Example:Answer
Answer: I usually use fetch or axios inside useEffect or a custom hook. I track loading, data, and error state, and abort the request on unmount with AbortController so the component does not update after leaving the screen. Then I render loading UI, error UI, or the data list.
useEffect(() => {
const c = new AbortController();
fetch(url, { signal: c.signal })
.then((r) => r.json())
.then(setData)
.catch((e) => {
if (e.name !== 'AbortError') setError(e);
})
.finally(() => setLoading(false));
return () => c.abort();
}, [url]);
🟡 Intermediate
2. API and UI implementation pattern?
Answer
Answer: I separate the HTTP client, domain service, query hook, and screen. The client handles base URL, auth, timeout, and normalized errors. The query hook manages cache/loading/retry. The screen renders loading, empty, error with retry, and success states. Mutations use optimistic updates only when rollback is safe. This separation makes networking testable and UI predictable.
3. API is called multiple times after opening a screen?
Answer
Answer: I first distinguish development-only Strict Mode effect replays from duplicate production requests. Then I inspect unstable effect dependencies, navigation remounts, duplicated focus listeners, and uncancelled or undeduplicated requests. I fix the ownership problem, cancel obsolete work, and add request deduplication or debounce only when the interaction requires it.
4. Axios vs fetch?
Answer
Answer: fetch is built in, small, and uses AbortController, but it does not reject on HTTP 4xx/5xx and needs manual JSON/error handling. Axios adds interceptors, timeout configuration, automatic transforms, and consistent errors, but adds a dependency. I choose based on the app's API layer, not because one is always faster.
5. Fetch/Axios vs React Query vs RTK Query?
Answer
Answer: fetch and Axios are HTTP clients; they send requests. React Query and RTK Query are server-state managers that sit above a client and provide caching, deduplication, retries, invalidation, and loading state. React Query is store-agnostic. RTK Query integrates with Redux. I do not compare them as direct substitutes: the query library can use fetch or Axios underneath.
6. Firebase implementation steps?
Answer
Answer: I create Firebase projects per environment, register Android package and iOS bundle ids, add google-services.json and GoogleService-Info.plist to the correct flavors/schemes, install the required modules, run Pods, and configure native plugins. I initialize only services used—Analytics, Crashlytics, Messaging, Remote Config—and validate release builds, APNs keys, ProGuard mapping, dSYM, and privacy disclosures.
7. GraphQL in React Native?
Answer
Answer: GraphQL lets clients request specific fields through a typed schema, reducing over-fetching and enabling one endpoint. Apollo or urql adds normalized cache, queries, mutations, subscriptions, and tooling. Risks include cache complexity, query cost, and backend authorization. I still secure every resolver server-side and handle offline/cache invalidation deliberately.
8. How do you avoid race conditions between multiple API calls?
Answer
Answer: Cancel the previous request or tag requests and accept only the newest response. This implements latest-response-wins behavior.
9. How do you cancel API requests?
Example:Answer
Answer: Pass an AbortController signal to fetch or Axios and abort in effect cleanup or when a newer request supersedes it.
const c = new AbortController();
fetch(url, { signal: c.signal });
c.abort();
10. Retry with exponential backoff?
Answer
Answer: Increase the delay after each transient failure, cap the maximum delay and attempts, and add jitter so clients do not retry together. Respect cancellation and Retry-After guidance, and fail immediately for non-transient errors.
11. Search results sometimes show an older response after the user typed a newer query?
Answer
Answer: That is a race condition. I debounce the query, abort the previous request with AbortController, or associate each request with an incrementing id and ignore responses that are not the latest. A server-state library can also cancel/deduplicate by query key. I never rely only on response arrival order.
12. The app freezes while parsing a very large API response?
Answer
Answer: JSON parsing and transformation are synchronous on the JS thread, so a huge payload blocks interactions. I reduce the payload at the API, paginate or stream data, parse/process it in chunks, move expensive transformations to native/background execution, and avoid normalizing everything before first paint. I profile Hermes CPU and measure the result instead of hiding the freeze behind a loader.
13. Token refresh creates an infinite 401 loop?
Answer
Answer: I coordinate refresh through one in-flight promise so concurrent 401 responses do not create a refresh storm. Requests that are safe to replay await that promise and retry once with the new credential; the refresh request itself is excluded from interception to prevent recursion. I keep refresh credentials in platform-protected storage, handle rotation atomically, preserve cancellation, and clear authentication state if refresh is rejected. Non-idempotent requests require an idempotency key or an explicit product decision before replay.
14. What is a request interceptor?
Answer
Answer: A request interceptor modifies or observes outgoing requests, commonly attaching auth, correlation IDs, locale, or safe telemetry.
15. What is a response interceptor?
Answer
Answer: A response interceptor transforms responses and centralizes normalized errors, telemetry, and eligible authentication recovery.
16. What is an Axios interceptor and why use it? Explain step by step?
Example:Answer
Answer: A request interceptor runs before a request and can attach access tokens, locale, or trace ids. A response interceptor runs before the caller sees the result and can normalize errors or handle 401. For refresh, I detect 401, prevent duplicate refresh with one shared Promise, obtain a new token, retry the original request once, and reject/log out if refresh fails. I guard against infinite retry loops.
api.interceptors.request.use((config) => {
config.headers.Authorization = `Bearer ${tokenStore.get()}`;
return config;
});
api.interceptors.response.use(
(r) => r,
async (error) => {
const req = error.config;
if (error.response?.status === 401 && !req._retried) {
req._retried = true;
const token = await refreshSingleFlight();
req.headers.Authorization = `Bearer ${token}`;
return api(req);
}
return Promise.reject(error);
},
);
17. Why are API calls triggered multiple times?
Answer
Answer: Check Strict Mode development remounts, unstable effect dependencies, missing cleanup, screen remounts, duplicate listeners, search without debounce, and query-library refetch defaults.
18. Why might an API be called three times from one click?
Answer
Answer: Check duplicate listeners, handler recreation, remounts, effects with unstable dependencies, missing debounce, and React Strict Mode's development-only repeated effect checks.
🔴 Senior
19. How do you cancel it, retry it, make it idempotent, and observe it?
Answer
Answer: Expose cancellation, retry only classified transient failures with bounds and jitter, attach idempotency keys to mutations, and emit state, latency, failure, and correlation telemetry.
20. How do you handle token refresh?
Example:Answer
Answer: I coordinate refresh through one in-flight promise so concurrent 401 responses do not create a refresh storm. Requests that are safe to replay await that promise and retry once with the new credential; the refresh request itself is excluded from interception to prevent recursion. I keep refresh credentials in platform-protected storage, handle rotation atomically, preserve cancellation, and clear authentication state if refresh is rejected. Non-idempotent requests require an idempotency key or an explicit product decision before replay.
let refreshing = null;
const token = () =>
(refreshing ??= refresh().finally(() => (refreshing = null)));
21. How do you secure API keys and secrets?
Answer
Answer: Assume anything shipped in JavaScript or native binaries is extractable. Keep real secrets on a backend, restrict public keys, use CI secret injection, and store session credentials in platform secure storage.
22. How would you design auth with token refresh + biometrics?
Answer
Answer: I coordinate refresh through one in-flight promise so concurrent 401 responses do not create a refresh storm. Requests that are safe to replay await that promise and retry once with the new credential; the refresh request itself is excluded from interception to prevent recursion. I keep refresh credentials in platform-protected storage, handle rotation atomically, preserve cancellation, and clear authentication state if refresh is rejected. Non-idempotent requests require an idempotency key or an explicit product decision before replay.
23. Offline support + sync when network returns?
Answer
Answer: I store reads in a local cache or DB, queue write mutations while offline, and listen to NetInfo. When online again I flush the queue with retries and backoff, using idempotent APIs when possible. For large offline-first apps I consider WatermelonDB or SQLite; for small caches MMKV is enough. I always show sync status in the UI.
Storage (AsyncStorage, MMKV, Secure Storage)
6 reviewed questions.
🟡 Intermediate
1. AsyncStorage vs MMKV vs Keychain/Keystore?
Answer
Answer: AsyncStorage is simple async key-value storage but slower and not for secrets. MMKV is much faster and often sync via JSI — good for preferences and cache. Tokens and secrets should go in Keychain on iOS and Keystore on Android through libraries like react-native-keychain or Expo SecureStore, not plain AsyncStorage.
2. How do AsyncStorage and MMKV differ?
Answer
Answer: AsyncStorage is asynchronous and unencrypted; MMKV is a faster synchronous JSI-backed key-value store with optional encryption capabilities.
3. What is MMKV?
Answer
Answer: MMKV is a fast synchronous C++/JSI key-value store useful for frequently accessed preferences and small cached values.
4. What should be stored in Keychain or Keystore-backed secure storage?
Answer
Answer: Store small high-value secrets such as refresh credentials or database-key wrappers when the platform and threat model permit it. Do not treat secure storage as a general database, and define accessibility, biometric gating, backup, device migration, logout deletion, and failure behavior. Minimize secret lifetime and never log decrypted values.
🔴 Senior
5. How do you migrate and version data stored in AsyncStorage or MMKV?
Answer
Answer: Namespace persisted data, store an explicit schema version, migrate through deterministic steps, and make interrupted migrations safe to resume. Validate decoded values, preserve rollback or reset behavior, and measure synchronous MMKV reads on startup. Sensitive credentials belong in platform-protected storage, not ordinary key-value stores.
6. MMKV, AsyncStorage, SQLite, or secure storage?
Answer
Answer: Use AsyncStorage for small nonsensitive async preferences, MMKV for frequent key-value access, SQLite for transactional queryable domain data, and Keychain or Keystore-backed storage for credentials.
Performance Optimization
38 reviewed questions.
🟢 Beginner
1. What is the difference between FlatList and ScrollView?
Example:Answer
Answer: ScrollView mounts all children, which suits small content. FlatList virtualizes long collections, mounting visible rows plus a buffer.
<FlatList
data={items}
keyExtractor={(item) => item.id}
renderItem={renderItem}
windowSize={7}
/>;
2. Why use FlatList instead of ScrollView?
Example:Answer
Answer: ScrollView renders all children at once, which is fine for small screens. FlatList virtualizes — it only mounts visible items plus a buffer — so it is required for long lists. Putting hundreds of items in a ScrollView hurts memory and scrolling performance, so for feeds and catalogs I use FlatList or FlashList.
<FlatList
data={items}
keyExtractor={(item) => item.id}
renderItem={renderItem}
windowSize={7}
/>;
🟡 Intermediate
3. Explain every important FlatList performance prop?
Example:Answer
Answer: initialNumToRender controls first-render count. maxToRenderPerBatch limits items per batch. updateCellsBatchingPeriod controls time between batches. windowSize controls how many viewport lengths remain mounted. removeClippedSubviews detaches offscreen views but can cause edge bugs. getItemLayout skips measurement for fixed sizes. I tune these only after profiling because smaller values trade memory for blank cells.
<FlatList
data={items}
keyExtractor={(item) => item.id}
renderItem={renderItem}
windowSize={7}
/>;
4. FlashList vs FlatList?
Example:Answer
Answer: FlatList is React Native's built-in virtualized list; FlashList is a maintained alternative with a different recycling and rendering implementation. Either can perform well, and results depend on row complexity, data updates, platform, and library version. I establish a release-build baseline, migrate a representative screen, compare frame timing, blank areas, memory, and correctness, and keep the simpler option unless measurements justify the dependency.
<FlatList
data={items}
keyExtractor={(item) => item.id}
renderItem={renderItem}
windowSize={7}
/>;
5. FlatList scrolling is janky only on low-end Android devices. What do you do?
Example:Answer
Answer: I reproduce on a release build and compare JS FPS with UI FPS. If JS FPS drops, I profile renderItem, memoize rows, stabilize props, use getItemLayout when possible, and remove synchronous work from onScroll. If UI FPS drops, I inspect image decoding, overdraw, shadows, and native layout complexity. I resize images, tune windowSize and batch props after measurement, then retest on the same low-end device.
<FlatList
data={items}
keyExtractor={(item) => item.id}
renderItem={renderItem}
windowSize={7}
/>;
6. FlatList vs ScrollView vs SectionList?
Example:Answer
Answer: ScrollView mounts its children eagerly, which is simple and appropriate for bounded content. FlatList virtualizes data-backed rows and is usually the safer baseline when item count or row cost can grow, but it adds tuning and state-preservation considerations. I choose from measured memory, fill rate, interaction cost, and product constraints rather than a fixed item-count rule.
<FlatList
data={items}
keyExtractor={(item) => item.id}
renderItem={renderItem}
windowSize={7}
/>;
7. How do you debug memory leaks?
Answer
Answer: I reproduce a repeatable cycle such as opening and closing a screen twenty times, then compare heap and native memory. I inspect timers, listeners, AppState, sockets, native emitter subscriptions, image caches, navigation retention, and large closures. I use Android Profiler or Xcode Allocations/Leaks plus Hermes heap snapshots. Every subscription needs symmetric cleanup.
8. How do you improve a list with 10,000+ items?
Answer
Answer: I paginate or use cursor loading, prefer FlashList for demanding feeds, memoize rows, keep props stable, use fixed layouts where possible, serve correctly sized images, and avoid expensive work in renderItem. I measure JS and UI FPS and memory. If users need search, I query the backend or indexed local DB instead of filtering ten thousand objects on every keystroke.
9. How do you reduce app size (thinning / optimization)?
Answer
Answer: I enable Hermes, ship an Android App Bundle, split ABIs where needed, compress images, remove unused fonts and assets, enable R8, audit native dependencies, and use vectors where appropriate. On iOS I rely on App Store thinning and measure bundle size before release.
10. InteractionManager: when and why?
Answer
Answer: InteractionManager schedules JavaScript work after active touches and registered interactions finish. React Native documentation marks it deprecated and recommends requestIdleCallback for deferrable work, so I avoid introducing new runAfterInteractions dependencies. Neither API makes heavy work free: I split expensive computation, move suitable work off the JS thread, and measure responsiveness.
11. Reduce app launch and splash time?
Answer
Answer: I measure native launch, JS bundle load, React mount, and first meaningful paint separately. I keep splash work minimal, enable Hermes, defer analytics/prefetch with requestIdleCallback, avoid blocking storage and migrations, lazy-load modules, reduce provider work, and render a useful shell early. A splash screen should hide when the first usable screen is ready, not after every background task. I verify requestIdleCallback support in the target React Native version and still split or relocate CPU-heavy work because idle scheduling does not create a worker thread.
12. Users report memory increasing every time they open and close a screen?
Answer
Answer: I create a repeatable navigation loop and compare heap snapshots. I look for uncleared timers, event listeners, AppState subscriptions, native emitter callbacks, sockets, image references, and navigation routes retaining large params. I fix cleanup, avoid large closure captures, and verify memory reaches a stable plateau after garbage collection.
13. What does FlatList windowSize control?
Example:Answer
Answer: windowSize controls how many viewport lengths remain mounted around the visible area.
<FlatList
data={items}
keyExtractor={(item) => item.id}
renderItem={renderItem}
windowSize={7}
/>;
14. What is InteractionManager?
Answer
Answer: InteractionManager schedules JavaScript work after active touches and registered interactions finish. React Native documentation marks it deprecated and recommends requestIdleCallback for deferrable work, so I avoid introducing new runAfterInteractions dependencies. Neither API makes heavy work free: I split expensive computation, move suitable work off the JS thread, and measure responsiveness.
15. Where and how do you check app performance?
Answer
Answer: I separate JS thread, UI thread, startup, memory, network, and native CPU. React Native Performance Monitor gives JS/UI FPS; React Profiler shows render cost; Hermes Profiler shows JS CPU; Android Studio Profiler and Perfetto show CPU/memory/frames; Xcode Instruments shows Time Profiler, Allocations, and Leaks. Firebase Performance or Sentry measures production traces. I reproduce in release mode because debug is misleading.
16. Why do FlatList items need stable keys?
Example:Answer
Answer: Keys identify item instances across renders and support correct reconciliation and recycling. Index keys break identity when insertion, deletion, or reordering occurs.
keyExtractor={item=>String(item.id)}
17. Why stable keys in FlatList?
Example:Answer
Answer: Stable keys let React preserve item identity as data is inserted, removed, or reordered. Index keys can associate local row state with the wrong item when order changes; they are acceptable only for truly static lists. I prefer a stable domain identifier through keyExtractor.
<FlatList
data={items}
keyExtractor={(item) => item.id}
renderItem={renderItem}
windowSize={7}
/>;
18. key and keyExtractor — why are they important?
Answer
Answer: Keys give list items stable identity during reconciliation and recycling. An index key changes identity when items are inserted, deleted, or sorted, causing wrong local state, flicker, or animation bugs. keyExtractor should return a stable unique business id as a string. Changing keys intentionally forces remounting.
🔴 Senior
19. App launch takes 8–10 seconds — what do you do?
Answer
Answer: I measure first: splash time, JS TTI, and first meaningful screen. Then I enable Hermes, reduce work at startup, lazy-load non-critical modules, defer analytics with requestIdleCallback, shrink the bundle, avoid sync storage reads on boot, and ensure TurboModules are lazy. I fix the biggest measured chunk, not guesses. I verify requestIdleCallback support in the target React Native version and still split or relocate CPU-heavy work because idle scheduling does not create a worker thread.
20. How can closures contribute to memory leaks?
Answer
Answer: A long-lived closure keeps every referenced outer value reachable. If it captures large objects or native resources, garbage collection cannot reclaim them until the closure or references are released.
21. How do TurboModules improve performance?
Answer
Answer: They initialize lazily, use generated typed bindings, avoid Bridge serialization, and can expose low-overhead or synchronous operations when justified. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
22. How do you debug performance problems?
Answer
Answer: Measure release behavior, identify whether JS, React, UI, native, I/O, or network time is responsible, inspect traces, fix one bottleneck, and compare the metric again.
23. How do you diagnose a FlatList that freezes while scrolling?
Example:Answer
Answer: Check whether JS or UI FPS drops, profile rows and image decode, stabilize keys and meaningful props, use fixed layout where possible, then tune virtualization and retest.
<MemoRow item={item} />}
24. How do you diagnose and fix a memory leak?
Answer
Answer: Repeat a flow, compare post-GC heap or allocation snapshots, inspect JS and native retention, fix lifecycle ownership, and verify memory reaches a stable baseline.
25. How do you diagnose memory leaks?
Answer
Answer: Repeat a flow, collect heap or allocation snapshots after GC, and inspect listeners, timers, closures, stores, image caches, native delegates, and navigation retention.
26. How do you find performance bottlenecks?
Answer
Answer: Define the slow metric, reproduce in a profileable release build, and separate JavaScript, React rendering, UI-thread, native, I/O, and server time with DevTools, profilers, Instruments, or Android Studio.
27. How do you improve startup time?
Answer
Answer: Measure native launch, bundle load, React initialization, first render, and interactive time separately; defer noncritical SDKs, storage, parsing, modules, and assets while showing useful UI early.
28. How do you investigate an 8–10 second app launch?
Example:Answer
Answer: Break launch into native startup, bundle load, React init, first paint, and interactive time. Defer noncritical SDKs, imports, parsing, and storage, then measure again.
requestIdleCallback(() => initAnalytics());
29. How do you measure production performance safely?
Answer
Answer: Capture user-centered marks with Performance APIs, sample and aggregate by version and device class, strip sensitive data, and combine timings with crashes, ANRs, memory, and server telemetry.
30. How do you optimize FlatList?
Example:Answer
Answer: Keep rows cheap, keys stable, images sized, and renderItem focused. Memoize meaningful row boundaries, use getItemLayout for fixed heights, then tune virtualization after measuring JS FPS and memory.
<FlatList
keyExtractor={(i) => i.id}
getItemLayout={(_, i) => ({ length: 72, offset: 72 * i, index: i })}
/>;
31. How do you optimize a FlatList that freezes while scrolling?
Example:Answer
Answer: I first check JS FPS with the performance monitor. Usually the row is heavy or images are too large. I memoize row components, use stable keys, keep renderItem light, use getItemLayout when height is fixed, and resize images. Only then I tune windowSize and initialNumToRender. For very large lists I also consider FlashList.
<FlatList
data={items}
keyExtractor={(item) => item.id}
renderItem={renderItem}
windowSize={7}
/>;
32. How do you prevent image out-of-memory crashes?
Answer
Answer: Request sized URLs, downsample, cap concurrent decoding, set cache policy, avoid full-resolution list bitmaps and base64, and profile native bitmap memory.
33. How do you reduce JS thread blocking?
Answer
Answer: I profile first to confirm JS FPS is the problem. Then I split heavy work into chunks, defer non-critical work with requestIdleCallback, move expensive logic to native/JSI, avoid huge sync JSON parsing on the UI path, and keep list rows cheap. Long synchronous loops in JS freeze interactions even if native views exist. I verify requestIdleCallback support in the target React Native version and still split or relocate CPU-heavy work because idle scheduling does not create a worker thread.
34. How would you investigate a memory leak that grows over hours?
Answer
Answer: Take repeated heap snapshots, reproduce lifecycle cycles, inspect growing retainers such as timers, listeners, caches, and native subscriptions, then verify cleanup stops growth.
35. How would you safely process 10,000 API requests?
Answer
Answer: Use bounded concurrency, batching when supported, retries with capped jittered backoff for transient failures, rate-limit handling, and progress/error reporting. Do not start all requests at once.
36. The app's startup time changed from 2 seconds to 8 seconds after adding SDKs?
Answer
Answer: I split startup into native launch, JS load, provider initialization, and first meaningful paint. I inspect each new SDK for eager initialization, move analytics and non-critical setup after interactions, lazy-load modules, enable Hermes, and remove duplicate or heavy dependencies. I compare cold-start traces before and after each change and keep the splash visible only until usable UI is ready.
37. Why does a screen re-render every second with no visible state change?
Answer
Answer: Highlight updates and inspect timers, provider values, parent animation state, selectors, and navigation focus listeners that schedule state repeatedly.
38. Why does memory grow when navigating between screens?
Answer
Answer: Repeated navigation can expose uncleared subscriptions, timers, retained screens, image caches, global listeners, and closures holding large data. Compare snapshots after GC.
React Native Performance Profiling & DevTools
5 reviewed questions.
🔴 Senior
1. How do Hermes sampling profiles help diagnose JavaScript-thread stalls?
Answer
Answer: A Hermes sampling profile shows where the JavaScript runtime spends CPU time during the recorded interval. Capture the smallest reproducible interaction, convert or open the profile in the supported tooling, and inspect hot stacks, repeated serialization, expensive selectors, parsing, or synchronous loops. Correlate the CPU stack with user timing because a hot function is not automatically the cause of the visible delay.
2. How do you create and enforce a mobile performance budget?
Answer
Answer: Choose user-centered budgets such as cold-start percentile, screen-ready time, dropped-frame rate, memory ceiling, APK or AAB size, and critical API latency. Define the device class, network, build mode, and measurement method, then automate stable checks where practical and monitor real-user percentiles after release. Budgets need owners and an exception process.
3. How do you profile React Native performance across Android and iOS native tools?
Answer
Answer: On Android, use Android Studio Profiler and Perfetto or system traces for CPU, memory, frames, startup, and thread scheduling. On iOS, use Instruments templates such as Time Profiler, Allocations, Leaks, and Core Animation. Add React Native DevTools and Hermes profiling for JavaScript and React context, then correlate timestamps across layers instead of treating one tool as complete.
4. How do you use React Native DevTools to investigate unnecessary renders?
Answer
Answer: Record the interaction in the React Profiler, inspect expensive commits, and identify components rendering because props, context, or state changed. Use component inspection to verify the actual values and test whether state can move closer to its owner. Memoization is the last step after confirming that the render cost and prop stability justify it.
5. What is a reliable React Native performance-profiling workflow?
Answer
Answer: Define the user-visible symptom and one metric, reproduce it in a release build on a representative device, then determine whether JavaScript, React rendering, UI work, native code, memory, I/O, or network time is responsible. Capture a baseline trace, change one variable, repeat the same interaction, and compare percentiles rather than one run. Finish with regression monitoring and a performance budget.
Native Modules & Bridging
10 reviewed questions.
🟡 Intermediate
1. Have you implemented a native module? Give a strong example?
Answer
Answer: A good example is wrapping a proprietary payment, Bluetooth, battery, or document-scanning SDK. I define a small JS/TypeScript API, implement Kotlin and Swift methods, expose Promises for one-shot operations and events for streams, handle threading and lifecycle, map native errors into stable codes, and write an example app. Under New Architecture I use a TurboModule spec and Codegen.
2. How do you implement Codegen-generated native interfaces in Kotlin/Java and Objective-C++/Swift?
Answer
Answer: Run Codegen from the typed spec, implement the generated Android and iOS protocols, register the module or component, and keep conversion and threading behavior explicit. Build both platforms so signature drift is caught at compile time, then test errors and lifecycle behavior through JavaScript.
3. How does React Native communicate with native code?
Answer
Answer: Legacy React Native used an asynchronous batched Bridge with serialized payloads. Modern React Native uses JSI-backed typed integrations through Fabric and TurboModules.
4. How does legacy bridging work?
Answer
Answer: A class implements RCTBridgeModule on iOS or extends ReactContextBaseJavaModule on Android. Exported methods receive serializable values and resolve callbacks or Promises. Events travel through RCTEventEmitter or DeviceEventEmitter. Calls cross an async queue, so I avoid high-frequency or large payloads and clean listeners correctly. New modules should prefer TurboModules where supported.
5. How does native code send events to JavaScript?
Example:Answer
Answer: Native code emits named events through the platform React Native event mechanism; JavaScript subscribes with NativeEventEmitter and removes the subscription.
const sub = emitter.addListener('batteryChange', onLevel);
sub.remove();
6. What is a native module?
Answer
Answer: A native module exposes Swift, Objective-C, Kotlin, Java, or C++ capabilities to JavaScript through a defined React Native interface.
🔴 Senior
7. Difference between Bridge and JSI?
Answer
Answer: The Bridge was asynchronous and serialized every message to JSON, which added latency and prevented true sync calls. JSI shares references in memory between JS and native, so communication is lower overhead and can be synchronous when safe. That is why Reanimated worklets and TurboModules feel faster than old Bridge modules.
8. How do you migrate an old native module to the New Architecture?
Answer
Answer: Write a typed spec, enable Codegen, implement generated platform interfaces, register the TurboModule, and test release builds with the New Architecture. Keep an interop path only while required. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
9. When do you write a Native Module?
Answer
Answer: I write a Native Module when React Native or a library cannot expose a device API I need, when a third-party SDK is native-only, or when JS is too slow for heavy work like image processing. In New Architecture I prefer a TurboModule with a typed Codegen spec. I expose Promises for one-shot work and events for continuous updates.
10. When should you create a native module?
Answer
Answer: Create one for unavailable platform APIs, native-only SDKs, background integration, or measured compute and transfer costs that JavaScript cannot meet.
New React Native Architecture (Fabric, TurboModules, JSI)
18 reviewed questions.
🟡 Intermediate
1. Fabric and its advantages?
Answer
Answer: Fabric is the new renderer implemented around a shared C++ core. It creates immutable shadow trees, supports synchronous measurement, improves consistency between platforms, and lets React coordinate concurrent work and priorities more effectively. It does not make every app automatically fast; expensive JS renders and oversized images still require application-level optimization. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
2. How do you write a typed TurboModule spec in TypeScript?
Answer
Answer: Define an interface that extends TurboModule, use Codegen-supported types, and export it through TurboModuleRegistry.getEnforcing. Keep the contract small and platform-neutral, then run Codegen so Android and iOS implementations are checked against the generated interface. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
3. What is Codegen?
Answer
Answer: React Native Codegen reads typed JavaScript specifications and generates platform interfaces and glue code for TurboModules and Fabric Native Components. It reduces handwritten serialization and keeps the JavaScript contract aligned with native implementations, but native code still must implement the generated interfaces correctly.
4. Why did the New Architecture arrive and what is new?
Answer
Answer: It arrived to remove Bridge serialization, support synchronous access where required, align rendering with React concurrency, improve startup, and enforce typed native contracts. JSI is the direct C++ interface, Fabric is the renderer, TurboModules are lazy native modules, Codegen generates bindings, and Bridgeless mode removes reliance on the legacy Bridge. The interop layer helps old libraries migrate gradually. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
5. Why was the New Architecture introduced?
Answer
Answer: It removes Bridge bottlenecks and adds direct JSI integration, Fabric rendering, lazy typed TurboModules, Codegen, synchronous capability where safe, and support for modern React concurrency. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
🔴 Senior
6. A third-party library blocks migration to the New Architecture?
Answer
Answer: I verify whether the interop layer supports it and isolate the dependency behind an adapter. I test New Architecture builds on both platforms, check the maintainer roadmap, and assess alternatives. For a critical SDK I can create my own TurboModule/Fabric wrapper. I migrate incrementally rather than disabling the whole architecture without a documented risk and exit plan. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
7. Fabric vs TurboModules vs Codegen—what is each responsible for?
Answer
Answer: Fabric is the renderer and shadow-tree system; TurboModules expose non-UI native capabilities; Codegen creates consistent typed interface glue for modules and components. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
8. How do you handle a third-party SDK that does not support the New Architecture?
Answer
Answer: Use the interop path temporarily, isolate the SDK behind an adapter, assess the vendor roadmap, and consider a narrow custom wrapper before requiring Bridgeless operation. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
9. How does synchronous communication work in the New Architecture?
Answer
Answer: JSI host functions can return small deterministic native values immediately to JavaScript. Disk, network, database, and heavy native work should remain asynchronous. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
10. Third-party SDK does not support New Architecture — what then?
Answer
Answer: I isolate that SDK behind a thin wrapper, keep the interop/legacy path enabled for that module if needed, and check vendor support timeline. If critical, I may wrap the native SDK myself as a TurboModule. I would not block the whole app migration for one library without a migration plan. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
11. TurboModules, Codegen, and Bridgeless?
Answer
Answer: TurboModules replace legacy native modules, load lazily, and expose typed specs through Codegen. JSI provides access without JSON serialization. Bridgeless means core operation no longer depends on the old Bridge. To migrate, I write the TypeScript spec, run Codegen, implement generated native interfaces, register the module, and test both platforms and lifecycle/thread behavior. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
12. What are Codegen specifications?
Answer
Answer: Typed TypeScript or Flow specs describe native modules and components. Codegen generates matching Android, iOS, and C++ interface glue so contracts stay consistent.
13. What is Bridgeless Mode?
Answer
Answer: Bridgeless Mode means React Native core no longer depends on the legacy Bridge for communication — modules and renderer talk through JSI. It is part of finishing the New Architecture rollout. In practice it reduces dual-path complexity, but third-party libraries must be compatible or use the interop layer during migration. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
14. What is Fabric?
Answer
Answer: Fabric is React Native's C++-backed renderer. It owns the host and shadow trees, supports synchronous mounting capabilities, and aligns rendering with concurrent React. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
15. What is JSI, Fabric, and TurboModules?
Answer
Answer: JSI is the C++ JavaScript Interface that lets native code hold direct references to JS objects without JSON serialization. Fabric is the new renderer built on that model for better concurrent-friendly updates. TurboModules are the new native module system — lazy-loaded and typed via Codegen. Together they replace the slow async Bridge path and unlock faster, sometimes synchronous, native calls. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
16. What is JSI, and does it mean every native call should be synchronous?
Answer
Answer: JSI exposes C++ host objects and functions directly to JavaScript without Bridge serialization. Only small deterministic operations should be synchronous; I/O and heavy work remain asynchronous.
17. What is JSI?
Answer
Answer: JSI is a C++ interface that lets a JavaScript runtime interact with host objects and functions without JSON serialization through the old Bridge.
18. What is a TurboModule?
Answer
Answer: A TurboModule is a lazily initialized, Codegen-typed native module accessed through JSI. React Native 0.82 and later run only on the New Architecture; 0.81 was the final release that allowed the Legacy Architecture, so migration and fallback advice must be tied to the project's target release.
Animations
7 reviewed questions.
🟡 Intermediate
1. Animated API vs Reanimated — what runs on UI thread?
Answer
Answer: The built-in Animated API can use useNativeDriver for opacity and transforms, but it is limited. Reanimated runs worklets on the UI thread via JSI, so gesture-driven animations stay smooth even if JS is busy. Shared values update without React re-renders. For production gesture UI, companies expect Reanimated + Gesture Handler.
2. Animated vs LayoutAnimation vs Reanimated and gestures?
Answer
Answer: Animated handles value-driven animations and can offload supported properties with the native driver. LayoutAnimation animates the next layout change with a simple global configuration. Reanimated runs worklets and shared values on the UI runtime, making it better for gesture-driven interactions. I combine Reanimated with Gesture Handler for complex production gestures.
3. Custom navigation transition?
Answer
Answer: With React Navigation I configure screenOptions or per-screen animation and cardStyleInterpolator for JS stack, or choose supported native stack animations. For a fully interactive custom transition I use Reanimated shared values and Gesture Handler, while respecting reduced motion and avoiding expensive JS work during navigation.
4. How do Animated and Reanimated differ?
Answer
Answer: Animated is built in and can offload supported properties with the native driver. Reanimated runs worklets and shared values on a UI-side runtime for richer gestures and interactions.
5. What are Reanimated Shared Values?
Answer
Answer: Shared Values are mutable values available to UI-runtime worklets without causing a React render for every frame.
🔴 Senior
6. A Reanimated animation is smooth, but pressing a button during it responds late?
Answer
Answer: The animation may be on the UI runtime while the button's JS handler is waiting on a blocked JS thread. I profile JS CPU, remove synchronous computation from the event path, defer non-critical work, and move gesture-critical calculations to worklets where appropriate. Smooth animation does not prove the JS thread is healthy.
7. What are Reanimated worklets?
Answer
Answer: Worklets are small JavaScript functions transformed to execute in Reanimated's UI-side runtime.
Push Notifications
3 reviewed questions.
🟡 Intermediate
1. Push notification foreground, background, and killed handling?
Answer
Answer: In foreground I receive the message and decide whether to show a local notification. In background, OS notification payloads can display automatically while data handlers perform limited work. In killed state, delivery relies on native OS configuration and payload type; a JS listener alone is insufficient. I handle tap navigation after auth restoration and deduplicate messages by id.
2. Rich push vs silent push?
Answer
Answer: Rich push contains media or custom actions. On iOS a Notification Service Extension downloads and attaches content; on Android the notification library builds BigPicture or custom styles. Silent push has no visible alert and requests background processing—content-available on iOS or high-priority data on Android—but delivery and execution are not guaranteed. I do not use silent push as a reliable job scheduler.
3. What is the difference between notification payload and data payload?
Answer
Answer: A notification payload can be displayed automatically by the OS in background or killed state. A data-only payload is handled by app code and does not show UI unless I build it. I choose based on whether the OS should display directly or the app should process first.
Deep Linking
4 reviewed questions.
🟡 Intermediate
Continue the series
Open the Complete React Native Interview Handbook 2026 series page on Dev.to for the next part.
Top comments (0)