React Native interviews are no longer limited to components, props, and styling. Modern interviews also test JavaScript execution, React behavior, native architecture, performance, security, release engineering, debugging, coding, and system design.
I created this guide as a structured preparation checklist for developers at every experience level. It contains 719 interview questions with concise answers and syntax-highlighted code examples where code adds value, organized into 36 focused topics.
What this guide covers
- JavaScript fundamentals, closures, asynchronous execution, and output questions
- React fundamentals, hooks, React Compiler, and state management
- React Native architecture, native modules, Fabric, TurboModules, JSI, and Codegen
- Navigation, networking, storage, security, animations, and notifications
- Performance profiling, debugging, testing, builds, releases, and production incidents
- Coding exercises, mobile system design, scenario questions, and behavioral interviews
Tip: Bookmark this article and study one topic at a time. Answers and code examples are collapsed so you can test yourself first.
Table of contents
- JavaScript Fundamentals (19)
- Advanced JavaScript (12)
- ES6+ (11)
- Scope, Hoisting & Closures (10)
- Event Loop & Async JavaScript (1)
- Promises & Async/Await (12)
- React Fundamentals (14)
- React Hooks (11)
- React Compiler & Future React (5)
- React Native Basics (7)
- Components & Lifecycle (7)
- Styling & Layout (Flexbox) (11)
- Navigation (26)
- State Management (18)
- APIs & Networking (18)
- Storage (AsyncStorage, MMKV, Secure Storage) (13)
- Performance Optimization (31)
- React Native Performance Profiling & DevTools (9)
- Native Modules & Bridging (10)
- New React Native Architecture (Fabric, TurboModules, JSI) (40)
- Animations (25)
- Push Notifications (5)
- Deep Linking (7)
- Debugging & Troubleshooting (4)
- Build & Release Process (43)
- Testing (9)
- Security (4)
- Production Issues (2)
- System Design (24)
- Mobile Databases (SQLite, Realm & WatermelonDB) (8)
- Monorepos (Nx & Turborepo) (6)
- AI-Assisted Mobile Development (5)
- Coding Problems (116)
- Output-Based JavaScript Questions (120)
- Scenario-Based Questions (51)
- HR & Behavioral Questions (5)
JavaScript Fundamentals
19 questions
1. How do find() and filter() differ?
Show answer and example
find returns the first matching element or undefined. filter returns a new array containing every match, possibly empty.
Example code
const users = [{id: 1}, {id: 2}, {id: 2}];
users.find(x => x.id === 2); // first matching object
users.filter(x => x.id === 2); // all matching objects
2. How do includes() and indexOf() differ?
Show answer and example
includes returns a boolean and can find NaN; indexOf returns the first index or -1 and cannot match NaN.
3. How do map(), forEach(), filter(), and reduce() differ?
Show answer and example
map transforms and returns a same-length array; forEach performs side effects and returns undefined; filter returns all matching elements; reduce combines elements into one result.
4. How do push/pop and shift/unshift differ?
Show answer and example
push and pop add/remove at the end; unshift and shift add/remove at the front. Front operations generally require reindexing and are more expensive.
Example code
const queue = ['A', 'B'];
queue.push('C'); // add at end
queue.pop(); // remove from end
queue.unshift('Z'); // add at front
queue.shift(); // remove from front
5. How do slice() and splice() differ?
Show answer and example
slice returns a shallow copy of a range without mutating the source. splice mutates the source by deleting, replacing, or inserting elements.
Example code
const source = [1, 2, 3];
const copy = source.slice(0, 2); // [1, 2], source unchanged
source.splice(1, 1, 9); // source is [1, 9, 3]
6. What are primitive and reference data types?
7. What is the difference between == and ===?
Show answer and example
== performs type coercion before comparison; === compares type and value without coercion. Prefer === because coercion can produce surprising results; == null is occasionally used intentionally to match both null and undefined.
8. What is the difference between null and undefined?
9. What is the difference between prefix and postfix increment?
10. What is type coercion?
Show answer and example
Type coercion is implicit or explicit conversion between types. Operators such as loose equality and + may coerce operands, so explicit conversion and strict equality are usually clearer.
11. map vs forEach vs filter vs reduce?
Show answer and example
map returns a new transformed array of the same length. forEach only runs side effects and returns undefined. filter returns items that pass a condition. reduce combines all items into one value like a sum or object. In interviews I quickly say: map=transform, filter=keep, reduce=aggregate, forEach=side effect only.
12. Function declaration vs function expression?
Show answer and example
A function declaration is hoisted with its function body, so it can be called before its source line. A function expression is created when its assignment executes; with let or const it cannot be used before initialization. Prefer declarations for named reusable functions and expressions for callbacks.
13. How can you clone a nested object?
14. How do getters and setters work?
15. Shallow copy vs deep copy?
Show answer and example
A shallow copy duplicates only the top-level container, so nested objects still share references. A deep copy recursively duplicates the supported value graph. Prefer targeted immutable updates and use structuredClone or a domain-aware clone only when a true deep copy is required.
16. Type coercion, null vs undefined, and typeof null?
Show answer and example
undefined usually means missing or not assigned, while null is an intentional empty value. typeof null returns object because of a historical binary-tag bug preserved for compatibility; null is still a primitive. Loose equality coerces types, so I use strict equality except for deliberate patterns.
17. What is the difference between a shallow copy and a deep copy?
Show answer and example
A shallow copy duplicates only the top level, so nested values remain shared references. A deep copy recursively creates independent nested values.
18. find() vs filter()?
Show answer and example
find returns the first matching element or undefined and stops once it succeeds. filter examines the collection and returns a new array containing every match. Use find for one item and filter when the result is a collection.
Example code
const users = [{id: 1}, {id: 2}, {id: 2}];
users.find(x => x.id === 2); // first matching object
users.filter(x => x.id === 2); // all matching objects
19. What are JavaScript property descriptors?
Show answer and example
A data-property descriptor defines value, writable, enumerable, and configurable; an accessor descriptor defines get and set. Object.defineProperty can control these attributes.
Advanced JavaScript
12 questions
1. How do call(), apply(), and bind() differ?
Show answer and example
call invokes immediately with positional arguments, apply invokes immediately with an argument array, and bind returns a new function with fixed this and optional preset arguments.
2. How do the in operator and Object.hasOwn() differ?
Show answer and example
in checks both own and inherited properties. Object.hasOwn checks only an object's own property and is safe even for null-prototype objects.
3. How does the prototype chain work?
Show answer and example
When an own property is absent, JavaScript follows [[Prototype]] links until it finds the property or reaches null.
4. How is this determined in JavaScript?
Show answer and example
this is determined by the call site: method calls use the receiver, plain strict-mode calls use undefined, new uses the new instance, call/apply/bind set it explicitly, and arrows capture outer this.
5. Map and Set?
Show answer and example
Map stores key-value pairs with keys of any type and preserves insertion order. Set stores unique values. They are better than plain objects for dynamic keys, reliable size, and iteration. WeakMap and WeakSet hold object keys weakly, so they are useful for metadata that should not prevent garbage collection.
6. What does Object.create(proto) do?
7. What is currying?
8. What is the difference between pure and impure functions?
Show answer and example
A pure function returns the same result for the same inputs and has no observable side effects. An impure function may mutate state, perform I/O, read time/randomness, or depend on external mutable values.
9. Can bind change this on an already bound function?
Show answer and example
No. Calling bind again creates another wrapper but does not replace the original bound this value.
10. Debounce vs Throttle?
Show answer and example
Debounce waits for a quiet period and then runs, making it suitable for search input. Throttle permits at most one call per interval, making it suitable for scroll telemetry. Define leading, trailing, cancel, and flush behavior explicitly.
11. What is garbage collection?
Show answer and example
Garbage collection reclaims objects that are no longer reachable from application roots. Developers do not free JavaScript memory directly, but retained listeners, timers, closures, caches, or native references can keep objects reachable and cause memory growth.
12. What is the difference between prototype and proto?
Show answer and example
A constructor function's prototype becomes the [[Prototype]] of instances made with new. proto is a legacy accessor for an object's [[Prototype]]; prefer Object.getPrototypeOf and Object.setPrototypeOf.
ES6+
11 questions
1. How do &&, ||, ??, ?., and the ternary operator differ?
Show answer and example
&& returns the first falsy operand or last value; || returns the first truthy operand; ?? falls back only for null/undefined; ?. safely accesses nullish values; condition ? a : b chooses one expression.
2. How do default parameters work?
3. What are template literals?
4. What is destructuring in JavaScript?
5. What is the difference between rest and spread syntax?
6. Can arrow functions be used as constructors?
7. How do Object.assign({}, obj) and object spread differ?
8. Normal function, arrow function, and flying function?
Show answer and example
JavaScript has no standard concept called a flying function. Interviewers usually mean an arrow function, callback, higher-order function, or immediately invoked function. A normal function has its own this and arguments and can be a constructor. An arrow function captures this lexically, has no arguments object, and cannot be used with new. I clarify the term before answering.
9. Object.assign({}, obj) vs { ...obj }?
Show answer and example
Object.assign({}, source) and {...source} both create shallow copies of own enumerable properties. Spread is usually clearer for immutable updates, while Object.assign can write into an existing target. Neither clones nested values, so nested references remain shared.
10. Spread vs rest, destructuring, optional chaining, and nullish coalescing?
Show answer and example
Spread expands arrays or objects and is commonly used for immutable shallow copies. Rest collects remaining parameters or properties. Destructuring extracts values. Optional chaining safely returns undefined when a parent is nullish, and ?? supplies a default only for null or undefined, unlike || which also treats zero and empty string as missing.
11. What are Symbols used for?
Scope, Hoisting & Closures
10 questions
1. How do function declarations and function expressions differ?
Show answer and example
Function declarations are initialized during scope creation and can be called earlier in the scope. Expressions are evaluated at their assignment and cannot be called before initialization.
Example code
foo(); function foo(){} // works
bar(); const bar=function(){} // ReferenceError
2. What is hoisting?
Show answer and example
Before execution, JavaScript registers declarations in their scope. var is initialized to undefined, function declarations are callable, and let/const remain uninitialized in the temporal dead zone. Code is not physically moved.
Example code
console.log(a); // undefined
var a=10;
foo(); function foo(){}
3. What is the difference between var, let, and const?
Show answer and example
var is function-scoped and initialized to undefined when hoisted. let and const are block-scoped and stay in the temporal dead zone until declared; let can be reassigned, while const cannot. Prefer const, use let when reassignment is needed, and avoid var.
Example code
const user = {name:'Ada'}; user.name='Bob'; // allowed
for (var i=0;i<3;i++) setTimeout(()=>console.log(i)); // 3,3,3
for (let i=0;i<3;i++) setTimeout(()=>console.log(i)); // 0,1,2
4. What is the temporal dead zone (TDZ)?
5. Explain this in regular functions, arrow functions, and methods?
Show answer and example
In a method call, this is the object before the dot. In a plain strict-mode function it is undefined. call, apply, and bind set it explicitly. Arrow functions do not create their own this; they capture it lexically. That makes arrows useful for callbacks but unsuitable as constructors or methods that require a dynamic receiver.
6. How do arrow functions and normal functions differ?
Show answer and example
Arrow functions are concise and lexically capture this; they have no own this, arguments, super, or new.target and cannot be constructors. Normal functions receive this from the call site and can be used with new.
7. What are closures? Can you provide a React Native example?
Show answer and example
A closure is a function together with the lexical variables it can access after the outer function returns. In React Native, an event handler closes over values from the render that created it; this is useful for private state but can produce stale values when dependencies are omitted.
8. What are scope and variable shadowing?
Show answer and example
Global, function, and block scopes control visibility. Shadowing occurs when an inner declaration uses the same name and hides the outer binding within that inner scope.
9. What is lexical scope?
Show answer and example
Lexical scope means variable access is determined by where functions are written, not where they are called. Nested functions can resolve names through their outer source scopes.
10. What is the Temporal Dead Zone and hoisting?
Show answer and example
Hoisting means declarations are registered before execution. var is initialized with undefined, while let and const remain uninitialized in the Temporal Dead Zone until their declaration runs. Reading them in that period throws ReferenceError. Function declarations are fully available before their source line.
Event Loop & Async JavaScript
1 questions
1. Synchronous vs asynchronous code?
Show answer and example
Synchronous code runs to completion on the current call stack. Asynchronous operations schedule continuations through queues such as Promise microtasks or timer tasks, allowing the thread to process other work while I/O completes.
Promises & Async/Await
12 questions
1. What is a Promise, and what are its states?
Show answer and example
A Promise represents a future value. It begins pending and settles once as fulfilled with a value or rejected with a reason; a settled Promise cannot change state.
2. Callback, Promise, async/await, and callback hell?
Show answer and example
A callback is a function invoked later. Deeply nested callbacks create callback hell, making ordering and errors difficult. A Promise represents a future value and supports then, catch, and finally. async/await is syntax over Promises that makes control flow readable. I use try/catch with await and Promise.all when independent operations can run in parallel.
3. Callbacks, Promises, and async/await?
Show answer and example
Callbacks pass completion functions directly and can be difficult to compose. Promises represent one future result and support chaining and aggregation; async/await is syntax over Promises that makes control flow and try/catch error handling easier to read.
4. How do Promise.all, allSettled, any, and race differ?
Show answer and example
all fulfills when all fulfill and rejects on the first rejection; allSettled reports every outcome; any fulfills on the first fulfillment and rejects if all reject; race adopts the first settlement.
5. How do callbacks, Promises, and async/await differ?
Show answer and example
A callback is a function invoked later. A Promise models a future result with then, catch, and finally. async/await is syntax built on Promises that makes asynchronous control flow easier to read.
6. One rejects in Promise.all?
Show answer and example
Promise.all rejects as soon as any input rejects, so the combined Promise is not fulfilled. Other operations are not automatically cancelled and may continue; use allSettled when every outcome is required and explicit cancellation when unfinished work should stop.
7. Promise.all, allSettled, race, and any?
Show answer and example
Promise.all waits for all and rejects on the first failure. allSettled waits for every result and reports each status. race settles with the first settled promise, while any fulfills with the first success and rejects only if all fail. I use all for required parallel calls and allSettled when partial success is acceptable.
8. What happens if you call an async function without awaiting it?
Show answer and example
The call immediately returns a Promise and following code continues. The work still runs, but ordering and rejection handling may be lost unless the Promise is awaited or consumed with then/catch.
Example code
save(); navigate(); // navigation may happen first
await save(); navigate();
9. What happens if you don't await an async function?
Show answer and example
Calling an async function without await starts it and immediately returns a Promise. The caller continues, so ordering assumptions may break, and a rejection can become unhandled unless the Promise is returned, awaited, or given an explicit catch handler.
10. What happens when one Promise in Promise.all rejects?
Show answer and example
Promise.all rejects with that reason as soon as the rejection is observed. The other operations are not automatically cancelled and may continue running.
11. What is wrong with forEach(async ...)?
Show answer and example
forEach does not wait for async callbacks, so it fires all promises and continues immediately. That can cause wrong order and unfinished work. For sequential work I use for...of with await. For parallel work I use Promise.all or Promise.allSettled with map.
Example code
// sequential
for (const u of users) await save(u);
// parallel
await Promise.all(users.map(u => save(u)));
12. What are async generators?
React Fundamentals
14 questions
1. What is a closure? Give a React Native example?
Show answer and example
A closure is a function that remembers variables from its outer lexical scope even after that outer function has finished. For example, a counter function can keep a private count and return 1, then 2. In React Native, closures appear in useEffect, timers, and debounce. A common bug is a stale closure: setInterval with empty dependencies keeps logging the first count. I fix it with correct deps or a ref.
Example code
function makeCounter() {
let count = 0;
return () => ++count;
}
const c = makeCounter(); // 1, then 2
2. What is the JavaScript thread?
Show answer and example
The JavaScript thread runs React, business logic, and most handlers. Heavy synchronous work blocks JS-driven updates and makes interactions feel frozen.
3. Event delegation?
Show answer and example
Event delegation attaches one handler to a common parent and uses the event target to handle many children. It works because browser events bubble and reduces listeners for dynamic lists. React Native has no DOM; it uses the responder and gesture systems, so I do not claim DOM event delegation applies directly to native views.
4. HOC vs render props vs custom hooks — which do you prefer?
Show answer and example
A HOC takes a component and returns an enhanced component. Render props pass a function that decides what to render. Custom hooks reuse stateful logic without adding wrapper components. I prefer custom hooks for new function-component code because they avoid wrapper hell; I use HOCs for cross-cutting component behavior or legacy libraries and render props when the caller must control rendering.
Example code
const withLoading = Component => props =>
props.loading ? <ActivityIndicator /> : <Component {...props} />;
function useLoadingTask(task) { /* reusable state logic */ }
5. How do you perform an immutable deep state update?
6. How does native code send events to JavaScript?
7. Multiple setState in same event?
Show answer and example
React batches state updates from the same event and processes them before the next render. Setting the same captured value repeatedly does not accumulate changes; use functional updates such as setCount(c => c + 1) when each update depends on the previous one.
8. Prototypes and inheritance?
Show answer and example
Objects inherit through their internal prototype chain. A constructor's prototype becomes the prototype of objects created with new. Property lookup walks the object and then its prototypes. class is syntax over this mechanism. In React Native app code I prefer composition, but understanding prototypes explains methods, instanceof, and polyfills.
9. What happens when setState is called multiple times in one event?
10. What is reconciliation?
Show answer and example
Reconciliation is React's process of comparing element trees and scheduling the minimum host updates needed to reflect new props and state.
11. Why can long JavaScript work freeze a React Native UI?
Show answer and example
App logic runs on the JavaScript thread, so a long synchronous task prevents that thread from processing interactions and updates. Chunk work, defer it, or move CPU-heavy work to native/background execution.
12. Why should React state not be mutated directly?
13. What are Actions in React 19, and when are they useful?
Show answer and example
An Action is an async transition used for a data mutation and the state changes around it. React manages pending state, optimistic updates, errors, and form reset behavior around the Action. In React Native, the same pattern can coordinate an async save or submission, but React DOM form actions and progressive enhancement remain web-specific.
Example code
const [error, submitAction, pending] = useActionState(async (_, form) => {
await updateProfile(form);
return null;
}, null);
14. When is React Native the wrong choice?
Show answer and example
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.
React Hooks
11 questions
1. What are custom hooks?
Show answer and example
A custom hook is a function beginning with use that composes hooks to reuse stateful behavior rather than UI.
2. Class component vs function component?
Show answer and example
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.
3. Class lifecycle compared with hooks?
Show answer and example
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.
4. Explain the useEffect lifecycle?
5. How do you prevent infinite useEffect loops?
Show answer and example
Use correct dependencies and guards, avoid unstable literals in dependency arrays, prefer functional updates where appropriate, and ensure an effect does not unconditionally update its own dependency.
6. How does useState work internally?
Show answer and example
Hooks are stored by call order on a Fiber. useState reads a hook slot and update queue; its setter enqueues work and schedules another render.
7. What are stale closures in hooks?
Show answer and example
A stale closure occurs when a callback reads props or state captured by an older render. Include every reactive value in the dependency list, use a functional state update when deriving from prior state, or use a ref only when the latest mutable value is intentionally required.
8. What are stale closures?
Show answer and example
A stale closure is a callback that captures props or state from an older render, often in timers, listeners, or effects with incorrect dependencies.
Example code
useEffect(() => { const id=setInterval(() => console.log(count),1000); return () => clearInterval(id); }, [count]);
9. Why do stale closures occur in useEffect and event handlers?
Show answer and example
A callback captures values from the render that created it. Missing dependencies or a long-lived callback can therefore keep reading old props or state.
10. Why stale closures in useEffect / handlers?
Show answer and example
Effects and handlers capture values from the render in which they were created. If they outlive that render and are not recreated with correct dependencies, they continue reading old values. Fix the data flow instead of suppressing the exhaustive-deps warning.
11. What problem does useOptimistic solve in React 19?
Show answer and example
useOptimistic lets the UI show the expected result of an Action before the server confirms it. React returns to the authoritative value when the Action completes, so the application still needs a failure message or rollback policy. Use it only when the optimistic result is safe and conflicts can be reconciled.
Example code
const [optimisticLikes, addLike] = useOptimistic(likes, count => count + 1);
// Update immediately, then run the network mutation.
React Compiler & Future React
5 questions
1. How do you debug a regression introduced after enabling React Compiler?
Show answer and example
First confirm the regression disappears when compilation is disabled for the smallest affected scope. Review compiler diagnostics, purity violations, custom hooks, mutable external state, and third-party boundaries. Reduce the case, preserve trace and build details, apply an opt-out only where required, and report a reproducible issue while keeping the wider rollout controlled.
2. How would you roll out React Compiler safely in React Native?
Show answer and example
Verify support in the selected React and React Native toolchain, enable compiler linting first, and establish render and interaction baselines. Roll out to a small package or feature, compare bundle, build, rendering, memory, and crash metrics, then expand gradually. Maintain opt-out directives for proven incompatibilities and a quick rollback path.
3. React Compiler versus React.memo, useMemo, and useCallback: how do they differ?
Show answer and example
React.memo manually skips component rendering when props compare equal; useMemo caches a computed value; useCallback caches a function reference. React Compiler analyzes the program and can insert equivalent memoization automatically where safe. Manual APIs remain useful for explicit contracts, unsupported code, library boundaries, and measured cases the compiler cannot optimize.
4. What coding rules make a component compatible with React Compiler?
Show answer and example
Components and hooks must remain pure during render, avoid mutating props or previously created values, follow the Rules of Hooks, and keep observable side effects outside render. Unsupported patterns and hidden mutation can prevent optimization or expose existing bugs. Use the compiler's linting and diagnostics as migration feedback.
5. What is React Compiler, and how does it change manual memoization?
Show answer and example
React Compiler statically analyzes component and hook code and inserts safe memoization when the code follows React's rules. It can reduce routine useMemo, useCallback, and React.memo usage, but it does not make expensive work free or fix incorrect state ownership. Teams should measure generated behavior and remove manual memoization only when compatibility and performance are verified.
React Native Basics
7 questions
1. What is event bubbling?
Show answer and example
In the browser, bubbling sends an event from its target up through ancestors; capturing travels from the root toward the target. stopPropagation can halt propagation.
2. What is the UI thread?
Show answer and example
The UI or main thread paints native views and processes touch input. It must meet the frame budget for smooth interaction.
3. Which JavaScript values are falsy?
Show answer and example
The falsy values are false, 0, -0, 0n, an empty string, null, undefined, and NaN. Every other value, including [] and {}, is truthy.
4. How do CommonJS and ES modules differ?
Show answer and example
CommonJS uses require/module.exports and resolves at runtime. ES modules use declarative import/export, support live bindings, and are designed for static tooling and asynchronous loading.
5. What are iterators and generators?
6. package.json vs package-lock.json and Babel?
Show answer and example
package.json describes scripts, metadata, and dependency ranges. package-lock.json records the exact resolved dependency tree so CI and developers install reproducible versions, so it should be committed. Babel transforms modern JavaScript and JSX into syntax the target runtime understands; Metro invokes the React Native Babel pipeline.
7. What are Proxy and Reflect used for?
Show answer and example
Proxy intercepts operations such as get, set, and apply for validation, defaults, or observability. Reflect exposes corresponding default operations and return conventions, making proxy traps easier to forward correctly.
Example code
const p=new Proxy(target,{get(t,k,r){return Reflect.get(t,k,r)}});
Components & Lifecycle
7 questions
1. Does React Native use the DOM?
Show answer and example
No. React Native uses React's reconciler with native host components such as View and Text, not HTML DOM nodes.
2. Cancel async on unmount?
Show answer and example
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.
3. How did ref handling change in React 19?
Show answer and example
Function components can receive ref as a prop in React 19, reducing the need for forwardRef in new code. React 19 also supports cleanup functions returned from ref callbacks. Existing forwardRef code continues to work, so teams can migrate gradually rather than rewriting every component.
Example code
function AppInput({ref, ...props}) {
return <TextInput ref={ref} {...props} />;
}
4. Explain the Fiber architecture?
Show answer and example
Fiber represents rendering as prioritizable units of work. Each node tracks component state, props, effects, and relationships, allowing work to pause, resume, and support concurrent rendering.
5. How do feature flags differ from remote config?
Show answer and example
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.
6. How should errors from React 19 Actions be handled?
Show answer and example
Expected validation failures should be returned as typed Action state so the UI can render them next to the relevant input. Unexpected failures should be logged and allowed to reach an error boundary or a controlled mutation error state. Cancellation, duplicate submission, retry, and idempotency still need application-level policies.
7. What is a native UI component?
Show answer and example
It is a platform view such as a map or camera exposed as a React Native host component, with typed props and events.
Styling & Layout (Flexbox)
11 questions
1. How does React Native differ from React.js?
Show answer and example
Both use React components, hooks, and reconciliation. React.js targets the browser DOM and CSS; React Native targets native View, Text, and Image hosts styled through StyleSheet and Yoga.
2. What is the difference between synchronous and asynchronous code?
Show answer and example
Synchronous code runs in order and blocks until each operation finishes. Asynchronous work starts now and completes later through callbacks, Promises, or async/await, allowing JavaScript to remain responsive while waiting for I/O.
3. How do you build reusable custom components?
Show answer and example
I keep a small typed API, use composition instead of many boolean props, support accessibility and test IDs, expose style overrides carefully, and separate visual components from data fetching. For imperative behavior I use forwardRef and useImperativeHandle. A design system should centralize spacing, colors, typography, and interaction states.
4. What happens internally when you render a component?
Show answer and example
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.
5. What is Flipper?
Show answer and example
Flipper is a desktop plugin-based debugging platform historically used for network, layout, logs, and native inspection in React Native.
6. What is the difference between useEffect and useLayoutEffect?
Show answer and example
useEffect runs after paint and suits data or subscriptions. useLayoutEffect runs synchronously around commit before the user sees the frame, which is useful for measurement but can delay paint.
7. How do accessibility, privacy, and localization affect this design?
Show answer and example
They shape primitives, focus and motion, data collection and retention, permissions, text expansion, RTL layout, formatting, and test matrices from the start.
8. How do you investigate an Android ANR?
Show answer and example
Inspect Play ANR clusters and main-thread traces, reproduce with StrictMode or profiling, find synchronous I/O, locks, binder calls, initialization, or layout, and move blocking work off main.
9. How do you optimize FlatList?
Show answer and example
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.
Example code
<FlatList keyExtractor={i=>i.id} getItemLayout={(_,i)=>({length:72,offset:72*i,index:i})} />
10. How do you optimize a FlatList that freezes while scrolling?
Show answer and example
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.
Example code
<FlatList data={items} keyExtractor={item => item.id} renderItem={renderItem} windowSize={7} removeClippedSubviews />
Profile before changing windowing props; stabilize renderItem and row props first.
11. How do you optimize a large feed?
Show answer and example
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.
Navigation
26 questions
1. How do you call an API in React Native?
Show answer and example
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.
Example code
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]);
2. How do you create a Promise that resolves after 10 seconds?
Show answer and example
I return a new Promise and resolve it inside setTimeout. The timeout places a callback in the task queue after at least ten seconds; it may run later if the call stack is busy. In production I also expose cancellation through AbortController when the operation is real I/O.
Example code
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
await delay(10_000);
3. Why use FlatList instead of ScrollView?
Show answer and example
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.
Example code
<FlatList data={items} keyExtractor={item => item.id} renderItem={renderItem} windowSize={7} removeClippedSubviews />
Profile before changing windowing props; stabilize renderItem and row props first.
4. navigate vs replace vs goBack?
Show answer and example
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.
5. Challenge C: API hook with loading/error?
Show answer and example
I keep data, error, and loading state in a custom hook, run the supplied fetcher in an effect, abort on cleanup, ignore AbortError, and return the three states to the screen.
6. Complete App Store and Play Store live process?
Show answer and example
I bump versions, create signed release binaries, run regression on real devices, upload dSYM/source maps and Android mapping, test TestFlight/internal track, complete privacy/data safety, screenshots, content rating, permissions, export compliance, and reviewer credentials. Then I use phased/staged rollout, monitor crashes, ANRs, startup, and reviews, and keep rollback/hotfix plans. Native changes require a new binary.
7. Explain execution context, call stack, microtask queue, and task queue?
Show answer and example
An execution context stores the current function's variables, scope, this value, and code. The call stack tracks active contexts. Synchronous code runs first. After the stack is empty, all microtasks such as Promise callbacks run, then a macrotask such as setTimeout runs. This order explains why Promises execute before timers.
Example code
console.log("A");
setTimeout(() => console.log("B"), 0);
Promise.resolve().then(() => console.log("C"));
console.log("D");
// Output: A D C B
8. Global variable vs local state vs global store?
Show answer and example
A global variable has no React subscription and can cause stale UI, shared-test leakage, and uncontrolled lifetime. Local state belongs near the component that uses it. A global store is appropriate when unrelated screens need coordinated updates. I keep state local by default and promote it only when sharing, persistence, or cross-feature workflows justify it.
9. How do Stack, Native Stack, Drawer, and Tabs differ?
Show answer and example
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.
10. How do you debug memory leaks?
Show answer and example
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.
11. How do you reset the navigation stack?
Show answer and example
Use navigation.reset or CommonActions.reset to replace route history, such as leaving only Home after login.
12. How does a JavaScript program run?
Show answer and example
The engine parses the source, creates execution contexts, compiles or interprets the code, and executes it on the call stack. Variables and functions are prepared during the creation phase, then statements run during the execution phase. In React Native, Hermes executes the JS bundle. Async operations are handled by native APIs and their callbacks return through the event loop.
13. How does the JavaScript event loop work?
Show answer and example
JavaScript runs synchronous work on one call stack. After the stack empties, it drains queued microtasks such as Promise callbacks before taking the next macrotask such as a timer. Long synchronous work blocks progress.
14. JavaScript vs TypeScript?
Show answer and example
TypeScript is JavaScript plus static types and compile-time tooling. It catches invalid props, API shapes, navigation params, and ref usage before runtime and improves refactoring. Types disappear at runtime, so API validation is still required. I use strict TypeScript, avoid broad any, model async states with unions, and generate types from schemas where possible.
15. Local store vs global store vs server state?
Show answer and example
Local UI state includes modal visibility and input values. Global client state includes auth and a cross-screen draft. Server state is remote, asynchronous, cacheable, and can become stale. I use component state for local data, Redux/Zustand for true shared client state, and React Query or RTK Query for server state rather than copying every API response into a global reducer.
16. What are the steps to publish an app to production?
Show answer and example
I set platform versions, test the release build on real devices, run regression, remove debug code, configure signing, and upload AAB and IPA. I complete store metadata, screenshots, privacy, data safety, rating, and export compliance, then use staged or phased rollout and monitor crashes and ANRs.
17. What causes 'Maximum call stack size exceeded'?
18. What does removeClippedSubviews do?
Show answer and example
It detaches offscreen native views to reduce traversal and memory pressure.
19. setTimeout vs setInterval, and how do you clean them?
Show answer and example
setTimeout schedules one callback after at least the requested delay; setInterval repeats approximately at an interval. Neither guarantees exact timing because callbacks wait for the call stack. In React Native I store the timer id in a ref and call clearTimeout or clearInterval in useEffect cleanup to avoid leaks and callbacks after unmount.
20. A screen feels slow. What is your investigation process?
Show answer and example
Define the user metric, reproduce on a representative device and profileable release build, trace JS, React, UI, native, I/O, and server time, fix one bottleneck, and remeasure.
21. Code splitting and lazy loading in React Native?
Show answer and example
React.lazy and dynamic imports can defer component evaluation, but React Native still commonly ships a single Metro bundle unless the runtime or OTA solution supports segmented bundles. I lazy-mount screens and defer heavy modules, but I do not promise web-style chunk loading automatically. Expo Router and platform tooling may improve route-level loading depending on the stack.
22. How do you debug a native crash that occurs only in release?
Show answer and example
Reproduce the exact signed build, collect and symbolicate its stack with matching dSYMs, R8 mappings, or NDK symbols, correlate release and device evidence, and verify through staged deployment.
23. How do you diagnose memory leaks?
Show answer and example
Repeat a flow, collect heap or allocation snapshots after GC, and inspect listeners, timers, closures, stores, image caches, native delegates, and navigation retention.
24. How do you structure a scalable React Native app?
Show answer and example
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.
25. What happens when a JavaScript function is called?
Show answer and example
A new execution context is pushed on the call stack. Its creation phase establishes lexical and variable environments, declarations, outer links, and this; its execution phase evaluates statements and assignments. It is popped when the call returns.
26. Which production signals do you monitor?
Show answer and example
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.
State Management
18 questions
1. What is JavaScript?
Show answer and example
JavaScript is a high-level, dynamically typed, multi-paradigm language with prototype-based inheritance. It runs in browsers, servers, and React Native engines and commonly uses a single-threaded event loop per runtime context.
2. Complete Redux flow?
Show answer and example
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.
3. Context API vs Redux — when should you use each?
Show answer and example
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.
4. How do you manage a complex form with 15+ fields?
Show answer and example
I avoid one global Context update per keystroke. I use React Hook Form or a focused custom form hook with field-level subscriptions, schema validation such as Zod/Yup, and separate server errors. Redux is unnecessary unless form drafts must be shared across screens; Zustand can fit multi-step drafts. The main goal is predictable validation without re-rendering every field.
5. How do you persist application state?
Show answer and example
Persist only durable slices through redux-persist, a store plugin, or explicit hydration, and version migrations.
6. How does MobX compare with Redux?
Show answer and example
MobX uses observables and reactions around mutable-looking state; Redux uses explicit immutable event transitions.
7. How does Recoil compare with Redux?
Show answer and example
Recoil models state as React-oriented atoms and selectors, while Redux centers a store, reducers, and dispatched events.
8. How does Zustand compare with Redux?
Show answer and example
Zustand offers small hook-based stores with little boilerplate; Redux offers stricter event conventions, middleware, and mature team tooling.
9. Old Redux vs Redux Toolkit?
Show answer and example
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.
10. Redux vs Context vs Zustand / React Query?
Show answer and example
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?
Show answer and example
Thunk allows dispatching functions that receive dispatch and getState, making straightforward asynchronous flows easy to express.
12. What is Redux Toolkit?
Show answer and example
Redux Toolkit provides standard Redux patterns with createSlice, Immer-backed reducers, sensible defaults, and RTK Query.
13. What is the React 19 context provider shorthand?
Show answer and example
React 19 allows a context object itself to be rendered as the provider instead of requiring Context.Provider. The value and update behavior are unchanged; this is a syntax simplification. Provider values should still be stable when avoidable re-renders matter.
Example code
<ThemeContext value={theme}><App /></ThemeContext>
14. When do you use Redux versus Context?
Show answer and example
Context suits low-frequency scoped dependencies such as theme. Redux suits complex shared state requiring explicit events, selectors, middleware, conventions, and DevTools.
15. Context, Redux Toolkit, Zustand, or TanStack Query—how do you choose?
Show answer and example
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 do lexical environment, scope chain, variable environment, and prototype chain differ?
Show answer and example
A lexical environment stores identifier bindings and an outer link; the scope chain follows those links. VariableEnvironment is associated historically with var/function bindings. The prototype chain is separate and resolves object properties through [[Prototype]].
17. What is Redux Saga?
Show answer and example
Saga uses generator effects to model cancellable workflows, races, and complex side effects.
18. Which React 19 features are web-specific rather than React Native features?
Show answer and example
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.
APIs & Networking
18 questions
1. What is the difference between Fetch and Axios?
Show answer and example
Fetch is built in and uses AbortController but needs more manual error, timeout, and JSON handling. Axios adds interceptors, timeout ergonomics, transforms, and a broader client API.
2. What is useEffect and when does it run?
Show answer and example
useEffect runs side effects after render — API calls, subscriptions, timers. With no dependency array it runs after every render. With [] it runs on mount and cleans up on unmount. With [a,b] it re-runs when those values change. I always return a cleanup function for timers, listeners, and AbortController.
3. Axios vs fetch?
Show answer and example
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.
4. Fetch/Axios vs React Query vs RTK Query?
Show answer and example
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.
5. GraphQL in React Native?
Show answer and example
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.
6. How do sequential and parallel await patterns differ?
7. How do you cancel API requests?
8. How do you cancel asynchronous work when a component unmounts?
9. Offline React Native design?
Show answer and example
I distinguish cached reads from queued writes. Reads come from a local DB/cache with freshness metadata. Writes are saved as durable operations with ids, timestamps, retry count, and idempotency key, then flushed when NetInfo reports connectivity. I use exponential backoff, conflict strategy, transactions, and visible sync status. MMKV fits small data; SQLite or WatermelonDB fits large relational datasets.
10. Q. How do you handle errors in async/await?
Show answer and example
"I wrap awaits in try/catch, or use .catch on promises. In UI I map errors to user-friendly messages and optionally retry network failures with backoff. Unhandled promise rejections are a red flag in reviews." Page 13/18
11. Retry a failed Promise?
Show answer and example
Wrap the operation in a function so each attempt creates a new Promise. Retry only transient failures, cap the attempt count, preserve the final error, and do not automatically retry non-idempotent writes unless the backend supports idempotency.
12. Retry with exponential backoff?
Show answer and example
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.
13. What is a request interceptor?
Show answer and example
A request interceptor modifies or observes outgoing requests, commonly attaching auth, correlation IDs, locale, or safe telemetry.
14. What is a response interceptor?
Show answer and example
A response interceptor transforms responses and centralizes normalized errors, telemetry, and eligible authentication recovery.
15. How do you cancel it, retry it, make it idempotent, and observe it?
Show answer and example
Expose cancellation, retry only classified transient failures with bounds and jitter, attach idempotency keys to mutations, and emit state, latency, failure, and correlation telemetry.
16. How do you ensure consistency when syncing large datasets on unreliable networks?
Show answer and example
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.
17. What does the use API do in React 19?
Show answer and example
The use API reads a resource such as a Promise or context during render. When it reads a pending Promise, rendering suspends to the nearest Suspense boundary; rejection reaches the nearest error boundary. Unlike hooks, use can be called conditionally, but the resource must be stable rather than recreated on every render.
Example code
function Profile({profilePromise}) {
const profile = use(profilePromise);
return <Text>{profile.name}</Text>;
}
18. What evidence would make you reverse this architecture decision?
Show answer and example
I would define falsifiable success and failure thresholds before deciding, then reverse when production data, a benchmark, or a changed constraint crosses them.
Storage (AsyncStorage, MMKV, Secure Storage)
13 questions
1. Code signing and keystore?
Show answer and example
Code signing proves who produced the binary and protects update integrity. Android uses a keystore containing the private signing key; Play App Signing can hold the app-signing key while CI uses an upload key. iOS uses certificates, private keys, provisioning profiles, app id, and entitlements. Losing keys can block updates, so they belong in secure backup/CI secret storage with controlled access.
2. How do you persist navigation state?
Show answer and example
Serialize navigation state on change and restore a compatible version at startup from storage.
3. How do you secure a React Native app?
Show answer and example
I assume the client can be reverse-engineered, never put real secrets in the bundle, store tokens in Keychain or Keystore, use HTTPS, validate on the backend, and use short-lived access tokens with refresh. I remove debug tooling and PII logs from release, enable R8, update dependencies, and add pinning or root detection only when the risk model requires it.
4. How do you secure tokens and confidential data?
Show answer and example
I store refresh tokens and private user credentials in iOS Keychain or Android Keystore through a maintained secure-storage library. Access tokens can remain short-lived in memory. AsyncStorage is not secure storage. I clear credentials on logout, avoid logging them, redact crash breadcrumbs, enforce backend expiry and revocation, and use biometric access control only as an additional local gate.
5. Reduce app launch and splash time?
Show answer and example
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 InteractionManager, 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.
6. Redux persistence?
Show answer and example
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.
7. When do you use Realm?
Show answer and example
Realm provides an object database with reactive queries and can simplify some offline models.
8. Where should secure data be stored?
Show answer and example
Credentials belong in Keychain, Android Keystore-backed storage, or SecureStore rather than plain AsyncStorage. Real service secrets remain on the backend.
9. Encryption/decryption in React Native?
Show answer and example
I prefer platform crypto and Keychain/Keystore over custom JavaScript cryptography. For local files I can generate an AES key, protect that key with the platform keystore, use authenticated encryption such as AES-GCM with a unique nonce, and version the ciphertext format. Keys, IVs, and data have different roles; hardcoding the encryption key in the JS bundle defeats the design.
10. How do you improve startup time?
Show answer and example
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.
11. How do you secure API keys and secrets?
Show answer and example
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.
12. How do you secure secrets and authentication data?
Show answer and example
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.
13. How does this behave on a low-end Android device with poor connectivity?
Show answer and example
I test CPU, memory, storage, startup, rendering, retries, and offline UX on representative constrained hardware and networks rather than extrapolating from a flagship device.
Performance Optimization
31 questions
1. Props vs state?
Show answer and example
Props are inputs passed from parent to child and should be treated as read-only. State is data owned by the component that can change over time and triggers a re-render when updated. If a sibling needs the same data, I lift state up to a common parent and pass it down as props.
2. What is the difference between FlatList and ScrollView?
Show answer and example
ScrollView mounts all children, which suits small content. FlatList virtualizes long collections, mounting visible rows plus a buffer.
Example code
<FlatList data={items} keyExtractor={item => item.id} renderItem={renderItem} windowSize={7} removeClippedSubviews />
Profile before changing windowing props; stabilize renderItem and row props first.
3. All important refs: useRef, createRef, forwardRef, callback ref, and useImperativeHandle?
Show answer and example
useRef returns a stable object across function renders and changing current does not re-render. createRef creates a new ref and is mainly for classes; calling it inside a function render would create a new ref each time. forwardRef lets a parent pass a ref through a custom component. A callback ref runs when the node attaches or detaches. useImperativeHandle limits the methods exposed through a forwarded ref.
Example code
const Input = forwardRef((props, ref) => {
const inner = useRef(null);
useImperativeHandle(ref, () => ({ focus: () => inner.current?.focus() }));
return <TextInput ref={inner} {...props} />;
});
4. Challenge B: Infinite scroll + pull to refresh?
Show answer and example
"I keep page and data in state, load more in onEndReached with a loadingMore guard, and reload page 1 in onRefresh. I always use a stable keyExtractor and memoized rows if the list is large." String(i.id)} renderItem={renderItem} onEndReached={loadMore} onEndReachedThreshold={0.4} refreshing={refreshing} onRefresh={onRefresh} />
5. FlashList vs FlatList?
Show answer and example
Both virtualize lists, but FlashList from Shopify is usually more efficient for large or complex lists. It recycles views more aggressively and often gives smoother scrolling with less blank space. FlatList is built-in and fine for moderate lists. In interviews I say: start with FlatList correctly optimized; use FlashList when lists are huge or still janky after basics.
Example code
<FlatList data={items} keyExtractor={item => item.id} renderItem={renderItem} windowSize={7} removeClippedSubviews />
Profile before changing windowing props; stabilize renderItem and row props first.
6. How do you optimize image loading?
Show answer and example
Request correctly sized images, compress assets, use caching and progressive loading, avoid base64 and full-resolution list images, and limit concurrent decode pressure.
7. How does parent re-rendering affect children?
Show answer and example
When a parent renders, React calls its children again by default. React.memo can skip a child if its props are shallow-equal. New inline objects and callbacks break that equality, so I use stable primitive props and useCallback only where profiling shows value. The best optimization is often moving state closer to the component that needs it.
8. PureComponent, pure function, and React.memo?
Show answer and example
A pure function has no side effects. React.PureComponent is a class optimization that shallowly compares props and state. React.memo is the function-component equivalent for props. Both fail to detect deep mutation and can be defeated by new object or function props, so I preserve immutability and stabilize only measured hot paths.
9. Q. Why stable keys in FlatList?
Show answer and example
"Stable keys keep item identity across updates. Using array index as key breaks recycling when order changes and causes wrong item state or flicker. I use a unique business id."
Example code
<FlatList data={items} keyExtractor={item => item.id} renderItem={renderItem} windowSize={7} removeClippedSubviews />
Profile before changing windowing props; stabilize renderItem and row props first.
10. Real DOM vs Virtual DOM in React Native?
Show answer and example
The real DOM is the browser's mutable document tree. The Virtual DOM is an in-memory description React reconciles before updating the host platform. React Native does not have a browser DOM; its host nodes are native views. Fiber still reconciles React elements, then Fabric or the legacy renderer applies changes to UIView and Android View objects.
11. Scope, global variables, IIFE, and ES modules?
Show answer and example
JavaScript has global, function, and block scope. Global variables live too long, create hidden dependencies, and can leak memory, so I prefer module scope or explicit state. An IIFE creates an immediate private scope, but ES modules now provide cleaner encapsulation. ES modules use import/export and are statically analyzable for tree shaking.
12. What causes unnecessary re-renders?
Show answer and example
Parent renders, unstable object or function props, broad context updates, over-wide selectors, and state updates with needless new references can all repeat work.
13. What does FlatList windowSize control?
Show answer and example
windowSize controls how many viewport lengths remain mounted around the visible area.
Example code
<FlatList data={items} keyExtractor={item => item.id} renderItem={renderItem} windowSize={7} removeClippedSubviews />
Profile before changing windowing props; stabilize renderItem and row props first.
14. What does maxToRenderPerBatch control?
Show answer and example
It limits how many list items are rendered in each incremental batch.
15. What does updateCellsBatchingPeriod control?
Show answer and example
It sets the delay between VirtualizedList rendering batches.
16. What does useCallback do?
17. What does useMemo do?
18. What is VirtualizedList?
Show answer and example
VirtualizedList is the core windowing engine behind FlatList and SectionList. It limits mounted rows around the visible viewport.
19. What is the difference between useMemo and useCallback?
Show answer and example
useMemo caches a computed value; useCallback caches a function reference. Both are performance tools whose dependencies must be correct.
Example code
const visibleItems = useMemo(() => filterItems(items, query), [items, query]);
const onPress = useCallback(id => selectItem(id), [selectItem]);
Memoize only after measuring a meaningful recomputation or child-render cost.
20. When should you not use useMemo?
Show answer and example
Do not memoize trivial calculations or unstable dependencies. Comparison, allocation, dependency maintenance, and correctness costs can exceed the saved work.
21. Why do FlatList items need stable keys?
Show answer and example
Keys identify item instances across renders and support correct reconciliation and recycling. Index keys break identity when insertion, deletion, or reordering occurs.
22. Why use Hermes?
Show answer and example
Hermes commonly improves startup, memory use, and runtime integration by avoiding large on-device parse work and optimizing for React Native workloads.
23. key and keyExtractor — why are they important?
Show answer and example
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.
24. useMemo vs useCallback vs React.memo?
Show answer and example
React.memo skips re-rendering a component if props are shallow equal. useMemo caches a computed value. useCallback caches a function reference so child memoization works. I do not wrap everything — I use them when profiling shows expensive re-renders or when passing callbacks to memoized list rows.
Example code
const visibleItems = useMemo(() => filterItems(items, query), [items, query]);
const onPress = useCallback(id => selectItem(id), [selectItem]);
Memoize only after measuring a meaningful recomputation or child-render cost.
25. useRef vs normal variable vs state vs global variable?
Show answer and example
A normal variable resets on every render. A ref survives renders but changing it does not re-render, so it fits timer ids and imperative values. State survives and triggers UI updates. A global variable is shared by all instances and has no React subscription, so it can cause stale UI and test leakage. I choose state for visible data, refs for non-visual mutable data, and an explicit store for shared data.
26. App launch takes 8–10 seconds — what do you do?
Show answer and example
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 InteractionManager, shrink the bundle, avoid sync storage reads on boot, and ensure TurboModules are lazy. I fix the biggest measured chunk, not guesses.
27. Feature flags in a large app?
Show answer and example
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.
28. Heavy third-party libraries slow the app — what do you do?
Show answer and example
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.
29. How do WeakMap and WeakSet differ from Map and Set?
Show answer and example
WeakMap and WeakSet hold object keys weakly, so entries do not keep otherwise unreachable keys alive and are not enumerable. Map and Set hold strong references and are iterable.
30. How do you diagnose and fix a memory leak?
Show answer and example
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.
31. When can React.memo, useMemo, and useCallback hurt?
Show answer and example
They add comparison, allocations, dependency maintenance, and cognitive cost; unstable props defeat them and stale dependencies cause correctness bugs.
Example code
const visibleItems = useMemo(() => filterItems(items, query), [items, query]);
const onPress = useCallback(id => selectItem(id), [selectItem]);
Memoize only after measuring a meaningful recomputation or child-render cost.
React Native Performance Profiling & DevTools
9 questions
1. How do you debug a React Native app?
Show answer and example
I reproduce with exact version/device, inspect JS logs and network, use React Native DevTools and React Profiler, debug native Android with Logcat/Android Studio and iOS with Xcode, and inspect production issues through Sentry/Crashlytics. I narrow the layer—JS logic, rendering, network, native module, build, or device—and verify the fix in release mode with regression tests.
2. Where and how do you check app performance?
Show answer and example
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.
3. How do Hermes sampling profiles help diagnose JavaScript-thread stalls?
Show answer and example
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.
4. How do you create and enforce a mobile performance budget?
Show answer and example
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.
5. How do you debug Hermes?
Show answer and example
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.
6. How do you profile React Native performance across Android and iOS native tools?
Show answer and example
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.
7. How do you use React Native DevTools to investigate unnecessary renders?
Show answer and example
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.
8. The Android app shows ANRs but no crashes?
Show answer and example
ANR means the main thread is blocked, not that the process threw an exception. I inspect Play Console ANR clusters, Perfetto traces, main-thread I/O, locks, BroadcastReceiver work, startup SDK initialization, and native synchronous calls. I move blocking work off main, shorten critical sections, and verify with release traces on affected device classes.
9. What is a reliable React Native performance-profiling workflow?
Show answer and example
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 questions
1. CodePush limitations and alternatives?
Show answer and example
CodePush/OTA can update JavaScript and bundled assets compatible with the installed native binary. It cannot add native modules, permissions, entitlements, SDK versions, or arbitrary binary changes. Store rules still apply, and a bad bundle needs rollback. Alternatives include Expo EAS Update, self-hosted bundle systems, or normal App Store/Play releases. I use runtime-version compatibility and staged rollout.
2. CodePush vs full store release — when which?
Show answer and example
I use CodePush or EAS Update for urgent JS fixes, A/B copy, and minor logic bugs. I use a full store release for native modules, SDK versions, permissions, entitlements, splash icons, or anything requiring a new binary, with a rollback plan.
3. How do you optimize a large app?
Show answer and example
I measure before changing code. Typical fixes are state localization, memoizing measured hot components, virtualized lists, image resizing/cache, avoiding synchronous work, lazy initialization, removing heavy libraries, reducing bridge/native crossings, Hermes, and startup deferral. I set budgets for startup, frame time, memory, bundle size, and network rather than saying 'useMemo everywhere'.
4. What commonly causes memory leaks in JavaScript and React Native?
Show answer and example
Common causes are uncleared timers, listeners, subscriptions, sockets, growing caches, globals, and long-lived closures retaining large data. React Native can also retain native-module or bridge references.
5. What is NativeEventEmitter?
Show answer and example
NativeEventEmitter is the JavaScript subscription interface for events emitted by a native module.
6. What is a native module?
Show answer and example
A native module exposes Swift, Objective-C, Kotlin, Java, or C++ capabilities to JavaScript through a defined React Native interface.
7. What is the React Native Bridge?
Show answer and example
The Bridge is the legacy asynchronous message queue between JavaScript and native code. It batches JSON-serialized payloads, adding overhead for chatty communication and preventing true synchronous calls.
8. When do you use callbacks versus Promises in native modules?
Show answer and example
Promises suit one-shot asynchronous results and standardized errors; events suit streams. Callbacks remain possible but are easier to invoke incorrectly.
9. How do you optimize React Native runtime performance?
Show answer and example
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.
10. When should you create a native module?
Show answer and example
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)
40 questions
1. AsyncStorage vs MMKV vs Keychain/Keystore?
Show answer and example
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. Environment setup for a React Native project?
Show answer and example
I pin Node and package manager versions, install JDK/Android Studio SDKs, Xcode/CocoaPods, and run the environment doctor. I keep environment-specific public configuration in typed files or build settings, never real secrets. Android flavors and iOS schemes select staging/production bundle ids, API URLs, icons, signing, and service files. CI uses the same locked versions and package lock.
3. Explain the architecture of React Native?
Show answer and example
React runs application logic on the JavaScript runtime, native views commit on the UI thread, and Yoga computes layout. The modern architecture uses JSI, Fabric, TurboModules, and Codegen instead of serialized Bridge traffic.
4. How do AsyncStorage and MMKV differ?
Show answer and example
AsyncStorage is asynchronous and unencrypted; MMKV is a faster synchronous JSI-backed key-value store with optional encryption capabilities.
5. How do you handle version updates and React Native migrations?
Show answer and example
I read release notes and Upgrade Helper, update one major layer at a time, create a migration branch, validate New Architecture/library compatibility, update Pods/Gradle/JDK/Xcode requirements, run codemods, rebuild native projects, and test critical flows on both platforms. I compare startup, crashes, and bundle size before rollout and keep a rollback plan.
6. How do you implement Codegen-generated native interfaces in Kotlin/Java and Objective-C++/Swift?
Show answer and example
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.
7. How do you write a typed TurboModule spec in TypeScript?
Show answer and example
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.
8. How does React Native communicate with native code?
Show answer and example
Legacy React Native used an asynchronous batched Bridge with serialized payloads. Modern React Native uses JSI-backed typed integrations through Fabric and TurboModules.
9. Old architecture in detail?
Show answer and example
The old architecture used the Paper renderer and Bridge. JS produced batched JSON messages for UIManager and native modules; native sent events back through the queue. Calls were asynchronous, data had to be serializable, modules often initialized eagerly, and frequent crossings added overhead. It was stable but limited synchronous layout access and modern concurrent rendering.
10. Q. What is Codegen?
Show answer and example
"Codegen reads TypeScript or Flow specs and generates native bindings for TurboModules and Fabric components so JS and native stay type-safe and in sync."
11. React Native threads and communication?
Show answer and example
The JS thread runs React and business logic. The UI/main thread renders views and handles native interaction. Layout work uses Yoga and renderer threads depending on architecture. Old RN communicated through an asynchronous serialized Bridge. New RN uses JSI and C++ foundations so Fabric and TurboModules can communicate more directly. Long JS work still blocks JS-driven behavior even when native UI exists.
12. What is MMKV?
Show answer and example
MMKV is a fast synchronous C++/JSI key-value store useful for frequently accessed preferences and small cached values.
13. What is the Shadow thread?
Show answer and example
In the classic renderer, the Shadow thread built the shadow tree and ran Yoga layout before changes reached the UI thread. Fabric integrates layout into its newer C++ renderer pipeline.
14. Why did the New Architecture arrive and what is new?
Show answer and example
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.
15. Why was the New Architecture introduced?
Show answer and example
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.
16. Difference between Bridge and JSI?
Show answer and example
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.
17. Dynamic linking of native libraries?
Show answer and example
Static libraries are copied into the app binary; dynamic frameworks are loaded at runtime and must be embedded and code signed. On Android native .so files must exist for supported ABIs and be packaged under jniLibs or an AAR. I check architecture slices, duplicate symbols, runtime search paths, minimum OS versions, license terms, and release stripping before integrating.
18. Explain React Native architecture (Bridge vs New Architecture)?
Show answer and example
JS thread runs React logic and UI thread paints native views. In the old architecture they talked through an async Bridge that serialized JSON, which became a bottleneck for chatty updates. The New Architecture uses JSI for direct communication, Fabric as the new renderer, and TurboModules for lazy native modules. It is faster, typed with Codegen, and can support synchronous calls when safe.
19. Explain React Native's New Architecture and why it matters?
Show answer and example
It replaces serialized Bridge traffic with JSI integration. Fabric renders UI, TurboModules expose typed lazy native APIs, and Codegen generates contracts, improving boundary cost, safety, and concurrent React support.
20. Explain the JS thread, UI thread, and rendering bottlenecks?
Show answer and example
JavaScript runs application and React work; the platform main thread processes input and commits native UI; Fabric coordinates layout and mounting. Heavy work on either timeline can miss frames.
21. Fabric vs TurboModules vs Codegen—what is each responsible for?
Show answer and example
Fabric is the renderer and shadow-tree system; TurboModules expose non-UI native capabilities; Codegen creates consistent typed interface glue for modules and components.
22. How do TurboModules differ from legacy native modules?
Show answer and example
TurboModules use JSI, Codegen-typed contracts, and lazy initialization rather than Bridge registration and serialized calls.
23. How do TurboModules improve performance?
Show answer and example
They initialize lazily, use generated typed bindings, avoid Bridge serialization, and can expose low-overhead or synchronous operations when justified.
24. How do you design the best scalable React Native architecture?
Show answer and example
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.
25. How do you make a build-vs-buy decision for a library?
Show answer and example
Assess product fit, maintenance, New Architecture support, platforms, security, license, size, performance, accessibility, API stability, and exit cost; prototype the risky path and inspect native code.
26. How do you reduce JS thread blocking?
Show answer and example
I profile first to confirm JS FPS is the problem. Then I split heavy work into chunks, defer non-critical work with InteractionManager.runAfterInteractions, 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.
27. How does synchronous communication work in the New Architecture?
Show answer and example
JSI host functions can return small deterministic native values immediately to JavaScript. Disk, network, database, and heavy native work should remain asynchronous.
28. Third-party SDK does not support New Architecture — what then?
Show answer and example
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.
29. TurboModules, Codegen, and Bridgeless?
Show answer and example
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.
30. What are Codegen specifications?
Show answer and example
Typed TypeScript or Flow specs describe native modules and components. Codegen generates matching Android, iOS, and C++ interface glue so contracts stay consistent.
31. What is Bridgeless Mode?
Show answer and example
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.
32. What is C++ used for in React Native?
Show answer and example
C++ provides shared cross-platform infrastructure for JSI, Fabric shadow nodes, Yoga, TurboModule bindings, and Hermes integration.
33. What is Fabric?
Show answer and example
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.
34. What is JSI, Fabric, and TurboModules?
Show answer and example
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.
35. What is JSI, and does it mean every native call should be synchronous?
Show answer and example
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.
36. What is JSI?
Show answer and example
JSI is a C++ interface that lets a JavaScript runtime interact with host objects and functions without JSON serialization through the old Bridge.
37. What is a TurboModule?
Show answer and example
A TurboModule is a lazily initialized, Codegen-typed native module accessed through JSI.
38. When do you write a Native Module?
Show answer and example
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.
39. When would you build a TurboModule or native component?
Show answer and example
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.
40. iOS SDK integration for folder/framework/xcframework or Git URL?
Show answer and example
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.
Animations
25 questions
1. Animated API vs Reanimated — what runs on UI thread?
Show answer and example
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?
Show answer and example
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. AppState and background tasks?
Show answer and example
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.
4. Custom navigation transition?
Show answer and example
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.
5. Explain Flexbox in React Native?
Show answer and example
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.
6. Explain every important FlatList performance prop?
Show answer and example
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.
Example code
<FlatList data={items} keyExtractor={item => item.id} renderItem={renderItem} windowSize={7} removeClippedSubviews />
Profile before changing windowing props; stabilize renderItem and row props first.
7. FlatList vs ScrollView vs SectionList?
Show answer and example
ScrollView renders everything and suits small content. FlatList virtualizes a one-dimensional list and SectionList adds grouped sections with headers. For large data I use FlatList or FlashList with stable keys, memoized rows, and pagination. Nested virtualized lists in the same direction are a warning sign.
Example code
<FlatList data={items} keyExtractor={item => item.id} renderItem={renderItem} windowSize={7} removeClippedSubviews />
Profile before changing windowing props; stabilize renderItem and row props first.
8. How do Animated and Reanimated differ?
Show answer and example
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.
9. How do you handle orientation and platform-specific UI/code?
Show answer and example
useWindowDimensions re-renders when dimensions change. I use Platform.select or .ios.tsx and .android.tsx files for meaningful platform differences and keep shared business logic common. Platform-specific UI should preserve the same domain behavior while following native navigation, permission, and design conventions.
10. How do you improve a list with 10,000+ items?
Show answer and example
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.
11. InteractionManager: when and why?
Show answer and example
InteractionManager.runAfterInteractions defers non-urgent JS work until active animations and touches finish. I use it after navigation for prefetching, analytics, or expensive preparation that would otherwise make the transition janky. It does not create a worker thread; the callback still runs on JS, so very heavy CPU work must be chunked or moved native.
12. Q. What is InteractionManager?
Show answer and example
"It lets me run heavy JavaScript after animations and interactions finish, so navigation transitions stay smooth. I use runAfterInteractions for non-critical startup or post-navigation work."
13. React Native WebView use cases and risks?
Show answer and example
WebView embeds web content for payments, legacy pages, rich documents, or authentication flows. I validate navigation URLs, restrict origins, avoid injecting secrets, sanitize messages, and define a narrow postMessage protocol. It is not a replacement for all native UI because performance, accessibility, navigation, and security differ.
14. SafeAreaView and responsive screen containers?
Show answer and example
Safe areas prevent content from overlapping notches, status bars, and home indicators. I prefer react-native-safe-area-context because it provides reliable insets and hooks across navigation setups. A reusable Screen component can combine insets, keyboard handling, scroll behavior, loading, and error states consistently.
15. StyleSheet.create vs normal style object?
Show answer and example
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.
16. What are Reanimated Shared Values?
Show answer and example
Shared Values are mutable values available to UI-runtime worklets without causing a React render for every frame.
17. What is InteractionManager?
Show answer and example
InteractionManager defers noncritical JavaScript work until active interactions and animations finish.
18. What is the native driver?
Show answer and example
The native driver serializes a supported Animated graph so transforms and opacity can update without a JavaScript callback every frame.
19. Why run animations on the UI thread?
Show answer and example
Per-frame work on the UI side avoids waiting for a busy JavaScript event loop and helps meet the frame budget.
20. How do you achieve responsive design?
Show answer and example
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.
21. How do you keep animations smooth under JS load?
Show answer and example
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.
22. How do you reduce flaky E2E tests?
Show answer and example
Wait on observable state instead of sleeps, use stable accessibility IDs, deterministic data, isolation and reset, control irrelevant animation and dependencies, and collect artifacts on failure.
23. What are Reanimated worklets?
Show answer and example
Worklets are small JavaScript functions transformed to execute in Reanimated's UI-side runtime.
24. What changed recently in React Native 0.82 through 0.86?
Show answer and example
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.
25. What platform differences should a senior React Native engineer know?
Show answer and example
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.
Push Notifications
5 questions
1. How do push notifications work in React Native?
Show answer and example
The OS delivers pushes through APNs on iOS and FCM on Android. The app registers a device token, sends it to the backend, and the backend asks Apple or Google to deliver. In React Native I commonly use FCM with Notifee. Foreground, background, and killed states differ, and killed state requires correct native setup.
2. Push notification foreground, background, and killed handling?
Show answer and example
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.
3. Rich push vs silent push?
Show answer and example
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.
4. What React Native libraries have you used, and how do you justify them?
Show answer and example
I answer by category and trade-off: React Navigation, Reanimated/Gesture Handler, React Query or RTK Query, MMKV/Keychain, Firebase, Sentry, React Hook Form, FlashList, and testing tools. I explain why each was selected, bundle/native impact, maintenance health, New Architecture support, and alternatives. Listing names without describing a production use case is a weak answer.
5. What is the difference between notification payload and data payload?
Show answer and example
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
7 questions
1. What is React Navigation?
Show answer and example
React Navigation is a common JavaScript navigation library providing stacks, tabs, drawers, linking, and navigation state for React Native.
2. Custom deep links vs Universal Links/App Links vs dynamic links?
Show answer and example
Custom schemes are easy but any app can claim them and they do not work as normal web fallbacks. Universal Links on iOS and verified App Links on Android use HTTPS and prove domain ownership, so they are preferred. Dynamic-link providers add attribution and fallback behavior, but provider support changes; I design around standard HTTPS links and add a provider only when marketing attribution requires it.
3. Google, Facebook, and Sign in with Apple flow?
Show answer and example
I configure each provider's app id, redirect URI, bundle/package identifiers, and platform files. The native SDK returns an authorization code or identity token, which I send to my backend. The backend validates it with the provider and issues my app's own access and refresh tokens. I do not trust profile data directly from the client. Apple requires nonce handling and Sign in with Apple when other social logins are offered on iOS.
4. How does deep linking work end to end?
Show answer and example
A URL reaches the OS, the OS matches the app's registered scheme, universal link, or app link, and launches or resumes the app. React Native reads the initial URL for a cold start or receives a URL event while running. React Navigation's linking config converts the path into a route and params. I validate the destination, wait for auth restoration, and redirect protected links through login before continuing.
Example code
1. Choose URLs: custom scheme such as myapp://product/42 plus production HTTPS links.
2. Android: add intent-filter for scheme/host/path; for verified App Links add autoVerify and host assetlinks.json.
3. iOS: add URL Types for custom schemes; add Associated Domains for Universal Links and host
apple-app-site-association.
4. Configure React Navigation prefixes and screen path mapping.
5. Handle cold start with Linking.getInitialURL and warm state with Linking.addEventListener('url', ...).
6. Parse and validate params; never trust a deep-link URL.
7. Restore auth/navigation state first; save a pending link if login is required.
8. Test terminated, background, foreground, installed, and not-installed cases.
const linking = {
prefixes: ['myapp://', 'https://app.example.com'],
config: {
screens: {
Home: '',
Product: 'product/:id',
ResetPassword: 'reset/:token',
},
},
};
<NavigationContainer linking={linking}>...</NavigationContainer>
5. Explain React Navigation architecture and common navigators?
Show answer and example
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.
6. How do deep links and universal/app links stay secure?
Show answer and example
Verify domains, allowlist and parse routes, pass protected destinations through auth and permission checks, validate expiring links on the server, and constrain redirects.
7. How does deep linking work?
Show answer and example
A linking configuration maps URL prefixes and paths to routes and parameters. Native intent filters or associated domains deliver cold and warm links to the app.
Debugging & Troubleshooting
4 questions
1. Crash vs ANR and how do you detect each?
Show answer and example
A crash terminates because of an unhandled JS/native exception or fatal signal. ANR is Android's Application Not Responding state when the main thread is blocked too long. Play Console, Crashlytics, Sentry, Android vitals, native tombstones, and ANR traces reveal them. For ANR I inspect main-thread I/O, locks, startup work, and large native operations; for crashes I symbolicate the exact stack.
2. Error Boundaries: what do they catch and not catch?
Show answer and example
An Error Boundary catches render, constructor, and lifecycle errors in its descendant tree and renders fallback UI. It does not catch event-handler errors, async Promise rejections, native crashes, or errors inside the boundary itself. I log componentDidCatch to Sentry and place boundaries around major navigation areas, while async errors are handled explicitly.
3. What is Reactotron?
Show answer and example
Reactotron is a development tool for inspecting application state, API activity, and timelines.
4. How do you measure production performance safely?
Show answer and example
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.
Build & Release Process
43 questions
1. What is React Native?
2. App thinning and app optimization?
Show answer and example
Apple App Thinning delivers device-specific architectures and assets; Android App Bundles let Play generate optimized APKs. I also enable Hermes and R8, compress images, remove unused fonts/assets/native libraries, audit dependencies, avoid universal APKs, lazy-load non-critical work, and inspect JS/native bundle size. Thinning reduces download size but does not replace runtime profiling.
3. Beta testing and adding test users?
Show answer and example
On iOS I add internal App Store Connect users or external TestFlight testers; external builds may require beta review. On Android I create an internal/closed testing track and add email lists or Google Groups. For backend test users I provide non-production accounts with safe data, document OTP/payment bypasses securely, and give App Review a working demo account when login is required.
4. Build release bundle?
Show answer and example
For Android, produce a signed release AAB or APK through Gradle; for iOS, archive the Release scheme and export or upload it through Xcode or Fastlane. Verify production configuration, signing, symbols, installation on a real device, and smoke tests before distribution.
5. Expo vs React Native CLI?
Show answer and example
Expo is the recommended starting point for most new apps in 2025–2026. It gives faster setup, OTA with EAS Update, and still supports custom native code through config plugins and continuous native generation. CLI/bare is useful when you need deep native customization from day one. In interviews I say: Expo by default unless native constraints clearly force bare workflow.
6. Git workflow in a team?
Show answer and example
I branch from the current integration branch, make small focused commits, rebase or merge according to team policy, push, open a PR, address review, pass CI, and merge with traceable history. I pull before long work, avoid committing secrets/generated noise, and never force-push shared main. Releases use protected branches/tags and documented hotfix flow.
7. Google Play release — what do you check?
Show answer and example
I upload an AAB with incremented versionCode, complete Data Safety, meet target API requirements, use Play App Signing, test on internal and closed tracks, then stage production rollout and watch crashes, ANRs, and reviews.
8. How do Android build variants and iOS schemes differ?
Show answer and example
Android combines product flavors and build types into variants. iOS schemes and build configurations select settings, targets, signing, and bundles.
9. How do you detect and act on production crashes?
Show answer and example
I integrate Crashlytics or Sentry, upload iOS dSYMs, Android mapping.txt, and JS source maps for each release. Alerts include version, device, OS, breadcrumbs, user-safe context, and frequency. I triage impact, identify regression version, reproduce, symbolicate, fix, test, and choose OTA only for compatible JS fixes; native crashes need a store release. I monitor the rollout after the fix.
10. How do you reduce app size (thinning / optimization)?
Show answer and example
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.
11. How do you secure API keys in a React Native app?
Show answer and example
Anything in the JavaScript bundle can be extracted, so client environment variables are not secrets. I restrict public client keys by bundle id, package, or signing fingerprint; keep real secrets behind a backend proxy; store user tokens in Keychain or Keystore; and inject build values from a CI secret manager. Client holds tokens; server holds secrets.
Example code
const API_KEY = process.env.API_KEY; // still extractable from the bundle
12. How do you verify Hermes is enabled?
13. How does Hermes differ from JavaScriptCore?
Show answer and example
Hermes is purpose-built for React Native and commonly precompiles bytecode at build time; JavaScriptCore is Apple's general JavaScript engine. Actual startup and memory results depend on the app.
14. ProGuard/R8 — what and why?
Show answer and example
R8 shrinks, optimizes, and obfuscates Android bytecode; ProGuard rules control what must be kept. It reduces APK size and makes reverse engineering harder, but obfuscation is not security. Reflection-heavy SDKs, serializers, and React Native modules may need keep rules. I test release builds and upload mapping.txt to Crashlytics/Sentry so obfuscated crashes are readable.
15. Unit tests, integration tests, snapshots, and E2E?
Show answer and example
Unit tests isolate pure functions/hooks. React Native Testing Library tests components through user-visible behavior. Integration tests cover connected flows with mocked boundaries. Snapshot tests catch structural changes but become noisy if overused; I keep them small and review diffs. Detox or Maestro covers critical end-to-end flows on real app builds.
16. What are microtasks and macrotasks?
Show answer and example
Promise.then and queueMicrotask schedule microtasks; setTimeout and setInterval schedule macrotasks. After synchronous work, all current microtasks run before the next macrotask.
17. What is CodePush? When do you use it?
Show answer and example
CodePush is an over-the-air update service that ships JavaScript and asset changes without waiting for store review. I use it for hotfixes, copy changes, and small JS bugs. It cannot change native code, dependencies, or permissions; those require a full store release. EAS Update provides the same model, and I keep rollout, versioning, and store policy limits clear.
18. What is Hermes and why do companies enable it?
Show answer and example
Hermes is a JavaScript engine optimized for React Native. It improves startup time and memory by using ahead-of-time bytecode instead of parsing a huge JS bundle on device. In interviews I also say how I verify it: check global.HermesInternal, and confirm hermes is enabled in Android/iOS build settings.
19. What is Hermes?
Show answer and example
Hermes is a JavaScript engine optimized for React Native, with build-time bytecode and mobile-focused runtime and garbage-collection behavior.
20. What is Metro?
Show answer and example
Metro is React Native's JavaScript bundler and development server, handling resolution, transforms, assets, and Fast Refresh.
21. What is app thinning?
Show answer and example
App thinning is Apple’s mechanism for delivering only the architecture, resolution-specific assets, and resources a device needs. Android App Bundles provide a similar optimized-per-device result. In React Native I use asset catalogs, correctly sized images, Hermes, and avoid unused assets.
22. What is the difference between TestFlight and internal testing?
Show answer and example
TestFlight is Apple’s iOS beta channel: internal testers receive builds quickly, while external testers need a short review. Android’s Play internal testing track serves fast pre-production QA. I test the exact release binary on both platforms.
23. iOS App Store review — what do you check before submit?
Show answer and example
I verify signing, provisioning, entitlements, privacy labels, ATS, permission strings, absence of private APIs, reviewer credentials when needed, and that the submitted release build is exactly what QA tested.
24. How can closures contribute to memory leaks?
Show answer and example
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.
25. How do you debug performance problems?
Show answer and example
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.
26. How do you decide between Expo and the React Native Community CLI?
Show answer and example
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.
27. How do you find performance bottlenecks?
Show answer and example
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.
28. How do you handle token refresh?
Show answer and example
Use one in-flight refresh promise, queue eligible failed requests, rotate and store credentials securely, retry each request once, and log out atomically if refresh fails.
Example code
let refreshing=null; const token=()=>refreshing ??= refresh().finally(()=>refreshing=null);
29. How do you integrate a third-party native SDK?
Show answer and example
Install with Gradle, CocoaPods, or SPM; configure platform permissions and lifecycle; wrap the SDK behind a narrow typed adapter; and test release builds.
30. How do you investigate random unreproducible crashes?
Show answer and example
Use symbolicated Sentry or Crashlytics groups, breadcrumbs, release and device filters, matching source maps and native symbols, and bisect recent native or engine changes.
31. How do you make accessibility part of architecture?
Show answer and example
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.
32. How do you plan a risky React Native upgrade?
Show answer and example
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.
33. How do you reduce APK or IPA size?
Show answer and example
Analyze the artifact, remove unused native dependencies and resources, optimize images, use app bundles or ABI splits, enable R8 where safe, and avoid oversized JS assets.
34. How do you secure APIs from a mobile app?
Show answer and example
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.
35. Should every app use certificate pinning?
Show answer and example
No. Pinning can reduce selected MITM risks but adds rotation and outage risk. Use it only when threat model or compliance justifies the cost, with backup pins, monitoring, rotation, and recovery.
36. What can CodePush or OTA updates change?
Show answer and example
OTA can generally update compatible JavaScript and assets, not native binaries, permissions, SDKs, or entitlements.
37. What can safely ship through an OTA update?
Show answer and example
Compatible JavaScript and assets can ship OTA; native binaries, permissions, SDKs, and entitlements cannot. Sign updates and bind them to a runtime compatibility version.
38. What is Hermes V1, and how do you evaluate its benefit?
Show answer and example
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.
39. What is the rollback plan if the rollout metric regresses?
Show answer and example
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.
40. What steps do you take before publishing to production?
Show answer and example
Test signed release builds on real devices; verify crash reporting, mappings, permissions, links, push, versions, privacy disclosures, performance, analytics, and environment configuration.
41. What would you build now, and what would you deliberately postpone?
Show answer and example
Build the smallest reversible slice that meets current scale, security, and reliability needs; postpone speculative abstractions while documenting triggers for pagination, caching, native work, or service extraction.
42. Which metric proves the optimization helped real users?
Show answer and example
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.
43. Why can ES modules be tree-shaken?
Show answer and example
Top-level declarative imports and exports let bundlers determine the dependency graph and remove unused exports without executing modules.
Testing
9 questions
1. What is NaN, and how should it be checked?
2. What is useRef?
3. What is middleware? Thunk vs Saga?
Show answer and example
Middleware sits between dispatch and reducers. Thunk lets actions be functions and is simple for request/dispatch flows. Saga uses generator effects such as takeLatest, race, retry, and cancellation, which fits complex orchestration but adds concepts and bundle size. I default to Thunk or RTK Query and use Saga only when workflows genuinely need its coordination model.
4. usePrevious, useLatest, useInterval, and useAsync?
Show answer and example
usePrevious stores the last committed value in a ref. useLatest keeps a ref synchronized with the newest value to prevent stale closures. useInterval stores the latest callback and cleans the timer. useAsync standardizes loading, result, error, cancellation, and optional retry. These hooks solve different lifecycle problems rather than merely hiding code.
5. How does Redux work under the hood?
Show answer and example
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.
6. How does useActionState work in React 19?
Show answer and example
useActionState connects an Action to its latest returned state and pending status. The Action receives the previous state followed by the submitted payload, which makes validation and server responses explicit. It is useful when submission state belongs to the mutation rather than to several independent useState calls.
Example code
const [result, save, isPending] = useActionState(saveProfile, {error: null});
// Call save(payload) from the submit interaction.
7. How would another team safely extend or replace this component?
Show answer and example
Provide a narrow versioned interface, ownership and ADRs, contract tests, observability, migration hooks, and an adapter boundary with no hidden global dependencies.
8. What is useEffectEvent, and how does it help avoid stale effect logic?
Show answer and example
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.
Example code
const onConnected = useEffectEvent(() => showToast(theme));
useEffect(() => connect(roomId, onConnected), [roomId]);
9. What is your testing strategy for a React Native application?
Show answer and example
Use unit tests for domain logic, Testing Library for visible component behavior, focused native integration tests, contract tests, and a small critical E2E suite.
Security
4 questions
1. What is an Axios interceptor and why use it? Explain step by step?
Show answer and example
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.
Example code
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);
});
2. HMAC and SSL pinning?
Show answer and example
HMAC signs a message with a shared secret so the server can verify integrity and authenticity; include timestamp and nonce to prevent replay. SSL pinning makes the app trust specific certificates or public keys instead of any system CA, reducing MITM risk. Pinning adds certificate rotation and outage risk, so I use backup pins and remote-safe migration. Neither protects a compromised device completely.
3. How do you handle token refresh without duplicate requests?
Show answer and example
The API layer owns one refresh promise; eligible failures await it and retry once. Refresh failure clears secure credentials atomically, and logout invalidates pending work.
4. What happens after process death, app upgrade, logout, or token expiry?
Show answer and example
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.
Production Issues
2 questions
1. How do Object.freeze() and Object.seal() differ?
Show answer and example
seal prevents adding, deleting, or reconfiguring properties but permits writes to writable properties. freeze adds protection against changing existing values. Both are shallow.
2. How do preventExtensions(), seal(), and freeze() differ?
Show answer and example
preventExtensions blocks new properties; seal also blocks deletion and reconfiguration; freeze additionally makes existing data properties non-writable. All are shallow.
System Design
24 questions
1. Design a production login flow?
Show answer and example
On launch I show a splash while reading the refresh token from secure storage. If present, I refresh the session; otherwise I show AuthStack. After login I keep the access token in memory, refresh token in Keychain/Keystore, reset to AppStack, and register the push token. On 401 a single-flight refresh retries queued requests. Logout revokes tokens, clears persisted user data, unregisters push where needed, and resets navigation.
2. Design a CI/CD pipeline for React Native?
Show answer and example
PRs run format, type, lint, tests, and targeted native builds. Main produces signed immutable artifacts, runs E2E, uploads maps and symbols, promotes the same artifact through staged tracks, and gates on health metrics.
3. Design a New Architecture migration for a large React Native application?
Show answer and example
Inventory native modules, view managers, code generation, animation, storage, navigation, and build tooling, then classify each dependency as compatible, replaceable, patchable, or blocking. Enable the architecture in controlled environments, migrate high-risk native boundaries incrementally, and compare startup, memory, rendering, crashes, and business flows. Preserve build-level rollback until both platforms and production cohorts are stable.
4. Design a background media-download manager?
Show answer and example
Model every download as a durable state machine keyed by content ID, with URL, destination, expected size, checksum, downloaded bytes, retry state, and ownership. Use platform background-transfer capabilities where continuity is required, publish throttled progress to active UI subscribers, and persist lifecycle checkpoints. Reconcile database state with actual files after restart and enforce storage, network, battery, and entitlement policies.
5. Design a feature-flag and remote-configuration platform for mobile?
Show answer and example
Ship safe defaults in the binary and fetch signed, versioned configuration with cache expiry and schema validation. Evaluate targeting deterministically from non-sensitive attributes, record exposure events, and provide kill switches for risky features. Configuration must not attempt to activate native capability absent from the installed binary.
6. Design a mobile analytics architecture that protects privacy?
Show answer and example
Define a typed event catalog with owner, purpose, allowed properties, retention, and consent requirement. Route events through one client that validates schemas, removes prohibited data, batches delivery, and honors opt-out state before collection. Version events deliberately and reconcile mobile telemetry with backend facts for critical business outcomes.
7. Design a modular CI/CD pipeline for Android and iOS?
Show answer and example
Use reproducible dependency installation, static analysis, unit tests, native build validation, signing isolation, artifact provenance, automated distribution, and release approval gates. Cache only deterministic inputs and keep credentials in the CI secret store with least privilege. Promote the same verified artifact through environments when platform rules allow, and capture version, commit, configuration, and dependency manifests.
8. Design a multi-brand or white-label React Native platform?
Show answer and example
Separate shared product capabilities from tenant configuration, assets, design tokens, entitlements, API endpoints, and native identifiers. Generate deterministic brand builds from validated configuration and keep brand-specific behavior behind typed capability flags rather than scattered conditions. CI should test shared journeys for every supported configuration and protect signing assets independently.
9. Design a production observability architecture for a React Native application?
Show answer and example
Combine crash reporting, handled-error telemetry, performance traces, structured breadcrumbs, release metadata, network correlation IDs, and business journey metrics. Normalize Android, iOS, JavaScript, and native symbols so incidents can be grouped accurately. Define service-level indicators such as crash-free sessions, startup percentiles, API failure rate, and checkout success, with alerts tied to user impact.
10. Design a push-notification delivery and navigation system?
Show answer and example
The backend stores token, platform, app version, user, locale, permission, and freshness metadata and removes invalid tokens from provider feedback. Payloads contain a typed navigation intent rather than arbitrary route data. The app uses one handler for foreground, background, and terminated launches, validates authentication and authorization, and queues navigation until the root navigator is ready.
11. Design a real-time chat architecture with offline support?
Show answer and example
Persist conversations and pending messages locally, use client-generated message IDs, and synchronize through a WebSocket plus a paginated REST recovery path. Model sending, sent, delivered, read, and failed states explicitly; preserve ordering with server sequence numbers rather than device clocks. Reconnect with backoff, request missed ranges, and keep media uploads separate from message creation.
12. Design a resilient React Native and PWA integration boundary?
Show answer and example
Define a versioned, allow-listed message protocol with schema validation, origin checks, correlation IDs, timeouts, and explicit success and error responses. Keep authentication and sensitive operations native where possible, and sign messages when the threat model requires integrity across the boundary. Navigation, lifecycle, retry, and backward compatibility must be specified rather than inferred.
13. Design a resilient payment flow in React Native?
Show answer and example
Treat the backend as the payment source of truth and model the client flow as explicit states such as initiated, awaiting authorization, processing, succeeded, failed, and unknown. Every create or confirm operation uses an idempotency key, and app restarts reconcile status from the backend. Sensitive data stays inside approved SDK boundaries, while logs exclude secrets and payment details.
14. Design a safe OTA update and staged-release strategy?
Show answer and example
Separate JavaScript-compatible OTA changes from updates that require a new native binary. Sign updates, enforce runtime compatibility, stage rollout by cohort, monitor crash and business metrics, and support automatic or manual rollback. App Store and Play Store releases should also use phased rollout, release gates, and immutable build provenance.
15. Design a scalable social feed?
Show answer and example
Clarify ranking, freshness, offline, media, ads, and consistency; use cursor pagination, cached entities, virtualization, sized CDN media, optimistic idempotent actions, an outbox, scroll preservation, and bounded caches.
16. Design a scalable, image-heavy social feed in React Native?
Show answer and example
Use cursor pagination, normalized entities, a virtualized list, stable row contracts, thumbnail-first image loading, memory and disk caching, and cancellation for off-screen work. Separate server state from local interaction state and prefetch conservatively based on measured scroll behavior. Track frame rate, blank cells, image failures, memory, cache hit rate, and time to first useful content.
17. Design a secure authentication and token-rotation architecture for a mobile app?
Show answer and example
Keep short-lived access tokens in memory when practical and refresh credentials in Keychain or Keystore-backed storage. Centralize authentication in one request layer, allow only one refresh operation at a time, replay eligible requests after success, and clear all protected state after definitive refresh failure. Add device binding or proof-of-possession only when the threat model justifies the complexity.
18. Design an offline-first mutation and synchronization engine for React Native?
Show answer and example
Write mutations to a durable local outbox with a client operation ID, entity version, payload, and retry metadata. Update the UI optimistically from the local database, then drain the outbox when connectivity and OS scheduling allow. The server must support idempotency and conflict detection; the client needs bounded retry, authentication recovery, dead-letter handling, and observable sync state.
19. Design an offline-first mutation flow?
Show answer and example
Write domain changes and an outbox record transactionally with client IDs and idempotency keys, update UI optimistically, retry under connectivity and OS constraints, and reconcile server acknowledgements and conflicts.
20. How do you design offline synchronization?
Show answer and example
Use a local database as source of truth, a durable outbox, idempotent APIs, bounded retry, connectivity and OS scheduling, explicit conflict rules, and visible sync state.
21. How would you design a production chat feature?
Show answer and example
Use a local database as UI source of truth, realtime transport for events, HTTP for history and media, client IDs and server sequences, message states, an offline outbox, pagination, virtualization, and reconnect rules.
22. How would you design auth with token refresh + biometrics?
Show answer and example
I keep short-lived access tokens in memory and store refresh tokens in Keychain/Keystore. Axios or fetch interceptors catch 401, run a single-flight refresh so parallel requests do not refresh thrice, retry the queue, and logout if refresh fails. Biometric unlock gates reading the refresh token. I also expire idle sessions and never put secrets in the JS bundle.
23. How would you redesign an app that has become difficult to maintain?
Show answer and example
I first map dependencies, state ownership, API boundaries, native integrations, and pain metrics. I define feature boundaries and shared platform services, introduce typed interfaces and tests around current behavior, then migrate one vertical feature at a time. I separate server state from client state, centralize design tokens/network/security, add observability and CI gates, and avoid a risky full rewrite unless evidence justifies it.
24. Offline support + sync when network returns?
Show answer and example
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.
Mobile Databases (SQLite, Realm & WatermelonDB)
8 questions
1. When do you use SQLite?
Show answer and example
Use SQLite for relational, queryable, transactional local data such as offline domain records and outboxes.
2. How do you design safe mobile database migrations?
Show answer and example
Version every schema, make migrations deterministic and resumable where possible, preserve a backup or recovery path, and test upgrades from every supported production version. Large transforms should avoid blocking startup and must tolerate interruption. Record migration duration and failures without logging sensitive records.
3. How do you optimize SQLite performance in React Native?
Show answer and example
Use transactions for batches, parameterized queries, appropriate indexes, pagination, projection of only required columns, and background work where supported. Inspect query plans and avoid one query per rendered row. Keep database access behind a repository or data layer so UI code cannot create uncontrolled query patterns.
4. How do you synchronize a local mobile database with a backend?
Show answer and example
Track server cursors or versions, client operation IDs, local dirty state, tombstones, and an outbox for mutations. Pull changes incrementally, apply them transactionally, push idempotent operations, and resolve conflicts with a domain-specific policy. Expose sync health and recoverable failures to the UI while keeping partial progress durable.
5. How should database encryption and key management work on mobile?
Show answer and example
Use a maintained encrypted database implementation when the threat model requires data-at-rest protection, and store the encryption key in Keychain or Keystore-backed storage rather than in source code or ordinary preferences. Define key rotation, logout cleanup, backup behavior, rooted-device limitations, and recovery. Minimize stored sensitive data even when encryption is enabled.
6. MMKV, AsyncStorage, SQLite, or secure storage?
Show answer and example
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.
7. SQLite versus Realm versus WatermelonDB: how do you choose?
Show answer and example
SQLite offers a mature relational foundation and direct query control but requires schema, mapping, and synchronization design. Realm provides an object-oriented database and reactive model with its own runtime and ecosystem trade-offs. WatermelonDB builds a lazy, observable data layer over SQLite-oriented storage for large React Native datasets. Choose from query shape, data size, reactivity, migration, sync, native footprint, maintenance, and team expertise.
8. When do you use WatermelonDB?
Show answer and example
WatermelonDB targets large offline-first datasets with lazy observable queries and synchronization patterns.
Monorepos (Nx & Turborepo)
6 questions
1. What is Metro Bundler?
Show answer and example
Metro is React Native's JavaScript bundler. It resolves modules, transforms JSX/TypeScript through Babel, creates the dependency graph and bundle/assets, and powers Fast Refresh. metro.config.js handles monorepos, aliases, asset extensions, transformers, and resolver settings. Metro is not the native build system; Gradle and Xcode still compile and package native code.
2. How do you optimize CI for a React Native monorepo?
Show answer and example
Use the dependency graph to run lint, tests, builds, and native validation only for affected projects while preserving periodic full verification. Cache package installation, JavaScript outputs, Gradle, CocoaPods, and derived artifacts only with complete deterministic keys. Separate fast pull-request feedback from signed release pipelines and monitor cache correctness and restore time.
3. How should native modules and Codegen be managed in a monorepo?
Show answer and example
Give each native-capable package a clear JavaScript API, Codegen specification, Android and iOS implementation, build metadata, and compatibility policy. Apps should consume released or workspace-resolved package entry points rather than native source through accidental relative paths. CI must validate Codegen and native builds for every affected application.
4. How would you structure a React Native monorepo with Nx?
Show answer and example
Keep deployable mobile apps separate from domain, UI, platform, tooling, and configuration libraries. Use project boundaries and tags to prevent feature packages from importing app internals, expose public entry points, and configure affected builds and tests from the dependency graph. Native projects retain clear ownership while shared TypeScript code remains platform-aware.
5. Nx versus Turborepo for a React Native monorepo: what are the trade-offs?
Show answer and example
Nx provides an explicit project graph, generators, affected commands, dependency constraints, and a larger integrated toolchain. Turborepo focuses on task orchestration and local or remote caching with fewer architectural opinions. The decision depends on repository scale, governance needs, existing package-manager workspaces, CI design, and whether the team values integrated conventions or a smaller surface.
6. What Metro configuration issues commonly appear in React Native monorepos?
Show answer and example
Common issues include duplicate React copies, unresolved workspace packages, files outside watched roots, symlink behavior, asset paths, platform extension resolution, and incompatible package exports. Configure project root, watch folders, resolver paths, and package-manager layout deliberately, then verify that React and React Native resolve to one compatible instance.
AI-Assisted Mobile Development
5 questions
1. How can AI assistants improve React Native debugging without replacing evidence?
Show answer and example
Provide a minimal reproduction, exact platform and versions, logs, stack traces, recent changes, and observed versus expected behavior. Ask for ranked hypotheses and the evidence that would distinguish them, then verify each hypothesis with profiling, instrumentation, or a controlled experiment. Keep the final root-cause analysis tied to runtime evidence.
2. How do you review AI-generated React Native code?
Show answer and example
Check requirements, platform behavior, lifecycle cleanup, thread assumptions, state ownership, error handling, accessibility, performance, security, dependency health, and test quality. Verify every API against the installed package version and inspect native configuration changes separately. Prefer a small understandable change over a large generated abstraction.
3. How should Cursor or GitHub Copilot be used safely in React Native development?
Show answer and example
Use AI assistants for bounded tasks such as scaffolding, test cases, migration checklists, documentation, and code exploration, while keeping the engineer accountable for requirements and output. Provide relevant local context, request assumptions and edge cases, review every dependency and platform API, and run the same tests and security checks required for human-written code.
4. How would you establish team governance for AI-assisted development?
Show answer and example
Define approved tools and repositories, prohibited data, human-review requirements, attribution rules, dependency policy, security scanning, and incident handling. Train developers on prompt hygiene and verification, record exceptions, and measure outcomes such as review time, escaped defects, and test quality rather than generated-line counts.
5. What data should never be sent to an AI coding assistant?
Show answer and example
Do not send production secrets, signing keys, access tokens, private customer data, proprietary source outside approved policy, incident payloads containing personal data, or confidential contracts. Follow organizational retention, model-training, regional, and vendor controls. Redact examples and use approved enterprise configurations when sensitive repositories are involved.
Coding Problems
116 questions
1. How do you build a character-frequency map?
2. How do you check whether a string is a palindrome?
3. How do you count vowels in a string?
4. How do you find the largest number in an array?
5. How do you implement a usePrevious hook?
6. How do you remove duplicates from an array?
7. How do you reverse a string?
8. What is the Virtual DOM?
Show answer and example
It is the conceptual in-memory description of UI elements that React compares before committing host updates; Fiber is the implementation that manages the work.
9. API and UI implementation pattern?
Show answer and example
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.
10. Array.prototype.map polyfill (Medium)?
What to say while coding: I include value, index and source arguments, support thisArg, and avoid invoking the callback for missing sparse indexes. A full spec polyfill has additional coercion details.Show answer and example
Expected result: Creates a new array and preserves sparse-array holes.
Example code
Array.prototype.myMap = function (callback, thisArg) {
if (this == null) throw new TypeError('Invalid receiver');
const source = Object(this);
const length = source.length >>> 0;
const result = new Array(length);
for (let i = 0; i < length; i++) {
if (i in source) {
result[i] = callback.call(thisArg, source[i], i, source);
}
}
return result;
};
11. Array.prototype.reduce polyfill (Medium)?
What to say while coding: The important edge case is an empty array without an initial value. I also skip sparse holes and pass all four callback arguments.Show answer and example
Expected result: Matches core reduce behavior, including a missing initial value.
Example code
Array.prototype.myReduce = function (callback, initialValue) {
const source = Object(this);
const length = source.length >>> 0;
let index = 0;
let accumulator;
if (arguments.length > 1) {
accumulator = initialValue;
} else {
while (index < length && !(index in source)) index++;
if (index >= length) throw new TypeError('Empty array');
accumulator = source[index++];
}
for (; index < length; index++) {
if (index in source) {
accumulator = callback(accumulator, source[index], index, source);
}
}
return accumulator;
};
12. Biometric authentication implementation?
Show answer and example
Biometrics should unlock a locally stored credential or approve an operation; they do not replace server authentication. I store the refresh token in Keychain/Keystore with biometric access control, prompt through a native library, then refresh the server session. I handle changed biometric enrollment, unavailable hardware, lockout, fallback PIN, and logout token revocation.
13. Challenge A: useDebounce?
Show answer and example
"I create state for the debounced value, start a timeout whenever the input changes, and clear the previous timeout in cleanup. That is the heart of debounce." function useDebounce(value, delay = 300) { const [v, setV] = useState(value); useEffect(() => { const id = setTimeout(() => setV(value), delay); return () => clearTimeout(id); }, [value, delay]); return v; }
14. Check a normalized palindrome (Easy)?
What to say while coding: I clarify whether case, spaces, punctuation and Unicode must be ignored. The two-pointer comparison avoids creating a second reversed string.Show answer and example
Expected result: true
Example code
function isPalindrome(value) {
const clean = value.toLowerCase().replace(/[^a-z0-9]/g, '');
let left = 0;
let right = clean.length - 1;
while (left < right) {
if (clean[left++] !== clean[right--]) return false;
}
return true;
}
isPalindrome('A man, a plan, a canal: Panama');
15. Check two strings are anagrams without sort (Easy/Medium)?
What to say while coding: This frequency-map solution avoids O(n log n) sorting. I first confirm normalization rules and mention that this exact style has appeared in React Native coding rounds.Show answer and example
Expected result: areAnagrams('listen', 'silent') returns true.
Example code
function areAnagrams(a, b) {
const left = a.toLowerCase().replace(/\s/g, '');
const right = b.toLowerCase().replace(/\s/g, '');
if (left.length !== right.length) return false;
const counts = new Map();
for (const char of left) {
counts.set(char, (counts.get(char) ?? 0) + 1);
}
for (const char of right) {
const next = (counts.get(char) ?? 0) - 1;
if (next < 0) return false;
counts.set(char, next);
}
return true;
}
16. Curry a fixed-arity function (Medium)?
What to say while coding: Currying converts one multi-argument function into a chain of partially applicable functions. I mention that fn.length has limitations with default and rest parameters.Show answer and example
Expected result: 6
Example code
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
}
return (...next) => curried.apply(this, [...args, ...next]);
};
}
const add = curry((a, b, c) => a + b + c);
add(1)(2)(3);
17. Currying and higher-order functions?
Show answer and example
A higher-order function accepts or returns functions. Currying transforms a multi-argument function like add(a,b) into add(a)(b), which enables reusable partial configuration. map, filter, debounce, middleware, and HOCs are higher-order patterns. I use currying when it improves composition, not just to make simple code clever.
Example code
const multiply = a => b => a * b;
const double = multiply(2);
double(5); // 10
18. Debounce search TextInput?
Show answer and example
Update local text immediately and debounce only the search side effect. Clear the previous timer when text changes, cancel the active request when possible, and ignore stale responses so an older query cannot replace newer results.
19. Deep clone nested arrays and plain objects (Medium)?
What to say while coding: I state the supported types. JSON stringify is not a true deep clone because it loses undefined, Date, BigInt and circular references. In modern production code, structuredClone may be appropriate.Show answer and example
Expected result: Returns an independent nested copy and preserves circular references.
Example code
function deepClone(value, seen = new WeakMap()) {
if (value === null || typeof value !== 'object') return value;
if (seen.has(value)) return seen.get(value);
if (value instanceof Date) return new Date(value);
const copy = Array.isArray(value) ? [] : {};
seen.set(value, copy);
for (const key of Reflect.ownKeys(value)) {
copy[key] = deepClone(value[key], seen);
}
return copy;
}
20. Fabric and its advantages?
Show answer and example
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.
21. Find the first non-repeating character (Easy)?
What to say while coding: The first pass counts; the second preserves original order. I return null explicitly when no unique character exists.Show answer and example
Expected result: c
Example code
function firstUnique(value) {
const counts = new Map();
for (const char of value) {
counts.set(char, (counts.get(char) ?? 0) + 1);
}
for (const char of value) {
if (counts.get(char) === 1) return char;
}
return null;
}
firstUnique('aabbcddee');
22. Firebase implementation steps?
Show answer and example
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.
23. Flatten a nested array without flat() (Medium)?
What to say while coding: I explain the recursive base case. For extremely deep input I would use an explicit stack to avoid call-stack overflow.Show answer and example
Expected result: [1, 2, 3, 4, 5]
Example code
function flatten(values) {
return values.reduce(
(result, value) =>
result.concat(Array.isArray(value) ? flatten(value) : value),
[],
);
}
flatten([1, [2, [3, 4]], 5]);
24. Flatten an array without flat?
Show answer and example
I recursively reduce the array. If an item is an array I flatten it and concatenate; otherwise I append it. Complexity is proportional to the total elements, while recursion depth depends on nesting. For extremely deep unknown input I use an explicit stack to avoid call-stack overflow.
Example code
const flatten = arr => arr.reduce(
(out, value) => out.concat(Array.isArray(value) ? flatten(value) : value), []
);
25. Flatten array any depth?
Show answer and example
Traverse each item recursively or with an explicit stack. Append scalar values and expand arrays until no nested array remains; clarify sparse arrays, mutation, recursion depth, and expected ordering before implementation.
26. Flatten object?
Show answer and example
Walk the object recursively and build each output key from its parent path and current property. Clarify how arrays, null, dates, separator characters, circular references, and empty containers should be handled.
27. Flatten only to a requested depth (Medium)?
What to say while coding: I validate depth in production and preserve remaining nested arrays once depth reaches zero. This exact depth-based variation has appeared in a React Native interview report.Show answer and example
Expected result: [1, 2, 3, [4]]
Example code
function flattenDepth(values, depth = 1) {
if (depth === 0) return values.slice();
return values.reduce((result, value) => {
return result.concat(
Array.isArray(value)
? flattenDepth(value, depth - 1)
: value,
);
}, []);
}
flattenDepth([1, [2, [3, [4]]]], 2);
28. Function.prototype.bind polyfill (Medium/Hard)?
What to say while coding: A good bind answer must discuss constructor usage: new should ignore the bound context. A fully spec-compliant implementation also handles metadata and edge cases.Show answer and example
Expected result: Returns a function with fixed context and optional partial arguments.
Example code
Function.prototype.myBind = function (context, ...preset) {
const target = this;
function bound(...later) {
const receiver = this instanceof bound ? this : context;
return target.apply(receiver, [...preset, ...later]);
}
bound.prototype = Object.create(target.prototype);
return bound;
};
29. Group objects by a property (Easy/Medium)?
What to say while coding: I define behavior for a missing property. In production I may prefer Map if keys are not strings or if prototype-safe storage matters.Show answer and example
Expected result: An object whose keys are professions and values are user arrays.
Example code
function groupBy(items, key) {
return items.reduce((groups, item) => {
const group = item[key] ?? 'unknown';
(groups[group] ??= []).push(item);
return groups;
}, {});
}
groupBy(users, 'profession');
30. Have you implemented a native module? Give a strong example?
Show answer and example
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.
31. How do you add a timeout to a Promise?
Show answer and example
Race the operation against a timer Promise that rejects. Clear the timer in a production helper and cancel the underlying operation when possible.
Example code
function withTimeout(p,ms){return Promise.race([p,new Promise((_,reject)=>setTimeout(()=>reject(new Error('Timeout')),ms))])}
32. How do you avoid race conditions between multiple API calls?
Show answer and example
Cancel the previous request or tag requests and accept only the newest response. This implements latest-response-wins behavior.
33. How do you cancel API requests on unmount?
Show answer and example
I use AbortController with fetch, or axios signal/cancel, and abort in the useEffect cleanup. That prevents setState on an unmounted screen and avoids race conditions when the user navigates quickly. For search, I also debounce and ignore outdated responses.
34. How do you check whether two strings are anagrams?
35. How do you find a missing number from 1 through n?
36. How do you find pairs that sum to a target?
37. How do you find the first non-repeating character?
38. How do you find the longest substring without repeating characters?
Show answer and example
Use a sliding window and map each character to its latest index. Move the left edge past a duplicate and track the maximum width.
Example code
function longest(s){const seen=new Map();let l=0,b=0;for(let r=0;r<s.length;r++){if((seen.get(s[r])??-1)>=l)l=seen.get(s[r])+1;seen.set(s[r],r);b=Math.max(b,r-l+1)}return b}
39. How do you find the maximum subarray sum?
40. How do you find the second-largest distinct number?
41. How do you flatten an array of any depth?
42. How do you group an array of objects by a property?
43. How do you implement a reusable API hook?
Show answer and example
Model data, loading, and error; start work in an effect; abort during cleanup; and ignore abort errors.
44. How do you implement a theme provider?
45. How do you implement a useDebounce hook?
46. How do you implement a useThrottle hook?
Show answer and example
Track the last publication time, update immediately when the interval has elapsed, otherwise schedule the remaining delay and clean up that timer.
47. How do you implement an Error Boundary?
48. How do you implement debounce for search TextInput?
Show answer and example
I keep the raw text in state for the input, then debounce that value with a custom useDebounce hook. A second effect depends on the debounced query and calls the API. That way we do not hit the server on every keystroke.
Example code
const [text, setText] = useState('');
const q = useDebounce(text, 300);
useEffect(() => { if (q) searchApi(q); }, [q]);
<TextInput value={text} onChangeText={setText} />
49. How do you implement debounce?
50. How do you implement deep equality?
Show answer and example
Return true for identical values, reject incompatible non-objects, compare key counts, then recursively compare corresponding properties. Production code must handle cycles, symbols, prototypes, and special types.
Example code
function deepEqual(a,b){if(Object.is(a,b))return true;if(!a||!b||typeof a!=='object'||typeof b!=='object')return false;const ka=Object.keys(a),kb=Object.keys(b);return ka.length===kb.length&&ka.every(k=>Object.hasOwn(b,k)&&deepEqual(a[k],b[k]))}
51. How do you implement infinite scroll with pull-to-refresh?
Show answer and example
Track data, page, refresh, and load-more state; replace data on refresh, append on pagination, guard duplicate requests, and provide stable list keys.
52. How do you implement memoize?
Show answer and example
Cache results by an argument key and return the cached value on repeated calls. Real implementations need an appropriate key strategy and eviction policy.
Example code
function memoize(fn){const c=new Map();return(...a)=>{const k=JSON.stringify(a);if(c.has(k))return c.get(k);const v=fn(...a);c.set(k,v);return v}}
53. How do you implement once?
54. How do you implement throttle?
55. How do you move all zeros to the end of an array?
56. How do you run an array of async functions sequentially?
57. How do you run-length compress a string?
58. How does JavaScript garbage collection work?
Show answer and example
Modern engines trace from roots such as globals and the stack, mark reachable objects, and reclaim unreachable ones; implementations also use generational optimizations.
59. How does legacy bridging work?
Show answer and example
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.
60. How should search TextInput requests be debounced?
Show answer and example
Keep the displayed query responsive and debounce the side-effecting API call, either with an effect timer plus cleanup or a stable debounced function.
61. Implement Promise.all (Hard)?
What to say while coding: Results preserve input order, not completion order. Promise.resolve supports plain values and thenables. The empty iterable resolves to an empty array.Show answer and example
Expected result: Resolves ordered results when all fulfill; rejects on the first rejection.
Example code
function promiseAll(values) {
return new Promise((resolve, reject) => {
const items = Array.from(values);
if (items.length === 0) return resolve([]);
const results = new Array(items.length);
let completed = 0;
items.forEach((item, index) => {
Promise.resolve(item).then(value => {
results[index] = value;
completed++;
if (completed === items.length) resolve(results);
}, reject);
});
});
}
62. Implement Promise.allSettled (Hard)?
What to say while coding: I convert each rejection into a fulfilled status object, so the outer Promise.all cannot fail because of an input rejection.Show answer and example
Expected result: Always fulfills with one status object per input.
Example code
function allSettled(values) {
return Promise.all(Array.from(values, item =>
Promise.resolve(item).then(
value => ({ status: 'fulfilled', value }),
reason => ({ status: 'rejected', reason }),
),
));
}
63. Implement a concurrency-limited promise queue?
Show answer and example
I keep a shared next index and start only limit worker loops. Each worker takes the next task, awaits it, stores the result at the original index, then takes another task. Promise.all waits for the workers. This limits pressure on APIs while retaining parallelism and can be extended with retries and allSettled behavior.
Example code
async function pool(tasks, limit) {
const results = new Array(tasks.length);
let next = 0;
async function worker() {
while (next < tasks.length) {
const i = next++;
results[i] = await tasks[i]();
}
}
await Promise.all(Array.from({ length: Math.min(limit, tasks.length) }, worker));
return results;
}
64. Implement debounce (Medium)?
What to say while coding: I preserve this and arguments, and expose cancel for component cleanup. In React Native search, I keep the debounced function reference stable and cancel it on unmount.Show answer and example
Expected result: Only the latest call runs after calls stop for delay milliseconds.
Example code
function debounce(fn, delay) {
let timer;
function debounced(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
}
debounced.cancel = () => clearTimeout(timer);
return debounced;
}
65. Implement debounce and throttle?
Show answer and example
Debounce clears the previous timer and schedules a new one, so only the final call after quiet time executes. Throttle tracks last execution or a pending timer so calls occur at most once per interval. I preserve this and arguments, expose cancel when useful, and clean it on component unmount.
66. Implement debounce?
Show answer and example
Return a wrapper that clears the previous timer and schedules the latest call after the delay while preserving this and arguments. A production implementation should define leading and trailing execution and expose cancel and flush behavior.
67. Implement setInterval using setTimeout (Hard)?
What to say while coding: Recursive setTimeout schedules after callback completion and avoids overlapping callbacks. Timers are not exact; backgrounding and a busy JS thread can delay them.Show answer and example
Expected result: Repeatedly invokes callback and returns a cancellation function.
Example code
function createInterval(callback, delay) {
let timer = null;
let active = true;
function tick() {
timer = setTimeout(() => {
if (!active) return;
callback();
tick();
}, delay);
}
tick();
return () => {
active = false;
clearTimeout(timer);
};
}
68. Implement throttle (Medium)?
What to say while coding: This is a leading-only throttle. I explicitly ask whether trailing calls, cancel, flush or maxWait are required because those change the implementation.Show answer and example
Expected result: At most one call runs per delay window.
Example code
function throttle(fn, delay) {
let waiting = false;
return function (...args) {
if (waiting) return;
waiting = true;
fn.apply(this, args);
setTimeout(() => {
waiting = false;
}, delay);
};
}
69. Implement throttle?
Show answer and example
Return a wrapper that runs at most once per interval while preserving this and arguments. Track the last execution and optionally schedule the latest trailing call; define leading, trailing, cancel, and flush semantics before coding.
70. Implement useDebounce and explain when to use it?
Show answer and example
useDebounce returns a value only after it has stopped changing for a delay. I use it for search input and validation to avoid one API call per keystroke. Cleanup clears the previous timeout; that reset behavior is the key difference from throttle.
Example code
function useDebounce(value, delay = 300) {
const [debounced, setDebounced] = useState(value);
useEffect(() => {
const id = setTimeout(() => setDebounced(value), delay);
return () => clearTimeout(id);
}, [value, delay]);
return debounced;
}
71. Jest and React Native Testing Library example strategy?
Show answer and example
I render the component, query by role/text/test id, perform user actions, and assert visible outcomes rather than internal state. I mock network at the service or MSW layer, use fake timers for debounce, and clean native module mocks. Tests should verify loading, success, empty, error, retry, and accessibility behavior.
72. Memoize a pure function (Medium)?
What to say while coding: This is an interview baseline, not a universal production cache. JSON keys fail for cycles and some values; a robust version uses nested Maps/WeakMaps and may need eviction.Show answer and example
Expected result: Repeated equivalent serialized arguments return the cached result.
Example code
function memoize(fn) {
const cache = new Map();
return function (...args) {
const key = JSON.stringify(args);
if (cache.has(key)) return cache.get(key);
const result = fn.apply(this, args);
cache.set(key, result);
return result;
};
}
73. Q. deep copy vs shallow copy?
Show answer and example
"Shallow copy clones only the top level, so nested objects are still shared. Deep copy clones nested structures too. In React I usually spread at each level I change. For true deep clone I use structuredClone when data is safe."
74. Remove duplicate array values (Easy)?
What to say while coding: Set preserves insertion order and uses SameValueZero equality. For duplicate objects, I would need a stable key or a custom comparison.Show answer and example
Expected result: [1, 2, 3]
Example code
function unique(values) {
return [...new Set(values)];
}
unique([1, 2, 2, 3, 1]);
75. Retry an asynchronous operation (Medium/Hard)?
What to say while coding: I clarify whether attempts includes the first call. In production I add exponential backoff, jitter, cancellation, retryable-error filtering and idempotency checks.Show answer and example
Expected result: Returns the first successful result or throws the final error.
Example code
async function retry(operation, attempts, delay = 0) {
let lastError;
for (let i = 0; i < attempts; i++) {
try {
return await operation();
} catch (error) {
lastError = error;
if (i < attempts - 1 && delay) {
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
throw lastError;
}
76. Reverse a string (Easy)?
What to say while coding: I use Array.from instead of split('') because it handles Unicode code points such as many emoji better. A follow-up can ask for an in-place array reversal.Show answer and example
Expected result: evitaN tcaeR
Example code
function reverseString(value) {
return Array.from(value).reverse().join('');
}
console.log(reverseString('React Native'));
77. Run async tasks with a concurrency limit (Hard)?
What to say while coding: I accept task functions rather than already-started Promises so concurrency can actually be controlled. I ask whether one rejection should fail fast or whether all results should be collected.Show answer and example
Expected result: Runs no more than limit tasks simultaneously and preserves result order.
Example code
async function runLimited(tasks, limit) {
if (limit < 1) throw new RangeError('limit must be positive');
const results = new Array(tasks.length);
let next = 0;
async function worker() {
while (true) {
const index = next++;
if (index >= tasks.length) return;
results[index] = await tasks[index]();
}
}
const workers = Array.from(
{ length: Math.min(limit, tasks.length) },
worker,
);
await Promise.all(workers);
return results;
}
78. S1. API is called multiple times after opening a screen?
Show answer and example
"I check React Strict Mode double-mount in development, unstable effect dependencies that recreate every render, missing abort/cleanup, screen remounting in navigation, and search without debounce. Then I fix deps, abort on cleanup, and debounce user input if needed."
79. Safely access a nested property by path (Easy/Medium)?
What to say while coding: For a fixed known path I prefer optional chaining. A helper is useful for dynamic paths, but production parsing needs clear rules for escaping and unsafe keys.Show answer and example
Expected result: Returns the city or Unknown without throwing.
Example code
function get(object, path, fallback) {
const keys = Array.isArray(path)
? path
: path.replace(/\[(\w+)\]/g, '.$1').split('.').filter(Boolean);
let current = object;
for (const key of keys) {
if (current == null) return fallback;
current = current[key];
}
return current === undefined ? fallback : current;
}
get(user, 'profile.address.city', 'Unknown');
80. Search results sometimes show an older response after the user typed a newer query?
Show answer and example
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.
81. Two Sum?
Show answer and example
I scan once with a Map from value to index. For each number I check whether target minus that number was already seen; if yes I return both indices. This is O(n) time and O(n) space, better than the O(n squared) nested-loop solution.
Example code
function twoSum(nums, target) {
const seen = new Map();
for (let i = 0; i < nums.length; i++) {
const need = target - nums[i];
if (seen.has(need)) return [seen.get(need), i];
seen.set(nums[i], i);
}
return [];
}
82. What are closures and lexical scope?
Show answer and example
Lexical scope means variable access depends on where a function is defined. A closure is a function that keeps access to that outer scope after the outer function returns. Closures power private counters, debounce, and event handlers, but a long-lived closure can retain large objects or capture stale React state.
83. What are closures, and how are they used in React Native?
Show answer and example
A closure lets a function retain access to variables from its lexical outer scope after the outer function returns. Closures power private state, handlers, timers, debounce, and custom hooks; stale closures occur when callbacks retain old render values.
Example code
function makeCounter(){let n=0; return ()=>++n;} const c=makeCounter(); c(); c(); // 1, 2
84. What are common React Native security mistakes?
Show answer and example
Common mistakes are storing refresh tokens in AsyncStorage, hardcoding keys that ship in the bundle, trusting client validation, logging PII, using HTTP, failing to abort requests on logout, and accepting deep links without authentication checks. I address these with secure storage, backend validation, and release-build hygiene.
85. What custom hooks are commonly asked, and how do they differ?
Show answer and example
useDebounce waits until values stop changing; useThrottle limits update frequency; usePrevious remembers the prior render; useFetch or useApi manages request state; usePagination manages page and load-more; useNetworkStatus exposes connectivity; useAppState exposes foreground/background state; useInterval and useTimeout manage timers; useAuth centralizes session logic; useForm manages validation. A custom hook reuses behavior, while a component reuses UI.
86. What is Redux middleware?
Show answer and example
Middleware runs between dispatch and reducers to implement logging, analytics, asynchronous flows, or policy around actions.
87. What is a higher-order function?
Show answer and example
A higher-order function accepts functions, returns a function, or both. map, filter, debounce, and middleware factories are common examples.
88. What is the difference between debounce and throttle?
Show answer and example
Debounce waits until calls stop for a quiet period; throttle limits execution to at most once per interval. Debounce fits search input, while throttle fits continuous scroll updates.
89. Why are API calls triggered multiple times?
Show answer and example
Check Strict Mode development remounts, unstable effect dependencies, missing cleanup, screen remounts, duplicate listeners, search without debounce, and query-library refetch defaults.
90. Why is JSON.parse(JSON.stringify(value)) not a general deep clone?
Show answer and example
It loses undefined and functions, converts Date to string, Map/Set to empty objects, NaN/Infinity to null, throws on BigInt and cycles, and does not preserve prototypes. Prefer structuredClone or a type-aware clone.
91. Why might an API be called three times from one click?
Show answer and example
Check duplicate listeners, handler recreation, remounts, effects with unstable dependencies, missing debounce, and React Strict Mode's development-only repeated effect checks.
92. useThrottle vs useDebounce?
Show answer and example
Debounce waits for a quiet period and then runs once, so it fits search. Throttle allows at most one run per interval, so it fits scroll analytics or resizing. Debounce favors the final event; throttle preserves periodic updates during continuous activity.
93. Android SDK integration when a source folder/project is provided?
Show answer and example
I inspect its Gradle plugin, namespace, minSdk, and dependencies, add it as an included module in settings.gradle, declare implementation project(':sdk'), resolve manifest conflicts, and expose only a thin wrapper to React Native. If it is a Git/Maven URL I prefer publishing or consuming a versioned Maven artifact rather than copying source, because updates and transitive dependencies are safer.
94. Android SDK integration when an AAR is provided?
Show answer and example
I place the AAR under android/app/libs or a dedicated library module, add flatDir only if no Maven metadata exists, add implementation files('libs/name.aar'), include transitive dependencies manually, add required permissions and ProGuard rules, initialize it in Application, then write a native module/view wrapper. I verify release builds because missing keep rules often appear only with R8.
95. How do you expose Kotlin code to React Native?
Show answer and example
Implement the generated TurboModule or legacy ReactContextBaseJavaModule contract, expose methods, package the module, and register or autolink it.
96. How do you expose Swift code to React Native?
Show answer and example
Add the native dependency, implement the generated or legacy module interface, bridge Swift through Objective-C or Objective-C++ where needed, and register it.
97. How do you expose battery level through a native module?
Show answer and example
Define a narrow asynchronous typed method, read BatteryManager or the iOS equivalent on the correct queue, resolve a Promise, and expose the generated module contract.
98. How do you implement Array.prototype.filter?
Show answer and example
Iterate existing indices, call the predicate with the standard arguments and optional thisArg, and push values whose predicate is truthy.
99. How do you implement Array.prototype.map?
Show answer and example
Iterate existing indices, call the callback with value, index, and source using the optional thisArg, preserve holes, and return a new array.
100. How do you implement Array.prototype.reduce?
Show answer and example
Use the supplied initial value when present; otherwise find the first existing element or throw for an empty array. Fold remaining existing indices with accumulator, value, index, and source.
101. How do you implement Function.prototype.bind?
Show answer and example
Capture the target, thisArg, and preset arguments and return a function that applies the target with combined arguments. A production polyfill must also preserve new-constructor behavior.
102. How do you implement Promise.all?
Show answer and example
Normalize each input with Promise.resolve, preserve index order, count fulfillments, resolve when all complete, and reject on the first rejection. Resolve an empty iterable immediately.
Example code
function promiseAll(ps){return new Promise((resolve,reject)=>{const a=Array.from(ps),r=[]; if(!a.length)return resolve([]); let n=0; a.forEach((p,i)=>Promise.resolve(p).then(v=>{r[i]=v;if(++n===a.length)resolve(r)},reject))})}
103. How do you implement Pub/Sub?
Show answer and example
Maintain subscriber sets by topic; subscribe adds and returns an unsubscribe function, while publish calls a snapshot of current subscribers.
Example code
function bus(){const m=new Map();return{subscribe(t,f){const s=m.get(t)||new Set();s.add(f);m.set(t,s);return()=>s.delete(f)},publish(t,v){[...(m.get(t)||[])].forEach(f=>f(v))}}}
104. How do you implement a cycle-safe deepClone?
Show answer and example
Return primitives directly, copy special types, register each source object in a WeakMap before recursing, and clone all own keys so cycles reuse the prior copy.
Example code
function deepClone(v,m=new WeakMap()){if(v===null||typeof v!=='object')return v;if(m.has(v))return m.get(v);if(v instanceof Date)return new Date(v);const out=Array.isArray(v)?[]:{};m.set(v,out);for(const k of Reflect.ownKeys(v))out[k]=deepClone(v[k],m);return out}
105. How do you implement an EventEmitter?
Show answer and example
Store listeners by event, let on add and off remove callbacks, emit over a snapshot, and implement once with a wrapper that unsubscribes before invoking.
Example code
class EventEmitter{constructor(){this.m=Object.create(null)} on(e,f){(this.m[e]??=[]).push(f);return this} off(e,f){this.m[e]=(this.m[e]||[]).filter(x=>x!==f)} emit(e,...a){(this.m[e]||[]).slice().forEach(f=>f(...a))} once(e,f){const w=(...a)=>{this.off(e,w);f(...a)};return this.on(e,w)}}
106. How do you implement an LRU cache?
Show answer and example
Use insertion order in a Map: on get, delete and reinsert the key as most recent; on set, refresh the key and evict the first key when over capacity.
Example code
class LRU{constructor(n=10){this.n=n;this.m=new Map()}get(k){if(!this.m.has(k))return;const v=this.m.get(k);this.m.delete(k);this.m.set(k,v);return v}set(k,v){this.m.delete(k);this.m.set(k,v);if(this.m.size>this.n)this.m.delete(this.m.keys().next().value)}}
107. How do you implement inheritance without class syntax?
Show answer and example
Call the parent constructor for own fields, set the child prototype to Object.create(parent.prototype), and restore child.prototype.constructor.
Example code
function Animal(n){this.name=n} Animal.prototype.speak=function(){return this.name}; function Dog(n){Animal.call(this,n)} Dog.prototype=Object.create(Animal.prototype); Dog.prototype.constructor=Dog;
108. How do you implement offline retry?
Show answer and example
Retry eligible transient network failures with bounded exponential backoff and jitter, then persist a replay-safe mutation in an outbox for reconnect.
109. How do you limit concurrent asynchronous operations?
Show answer and example
Start a fixed number of worker loops that claim the next index and await its work. Await all workers and store results by original index.
Example code
async function mapPool(items,limit,worker){const out=[],workers=[];let i=0;async function run(){while(i<items.length){const n=i++;out[n]=await worker(items[n],n)}} for(let n=0;n<Math.min(limit,items.length);n++)workers.push(run());await Promise.all(workers);return out}
110. How do you migrate an old native module to the New Architecture?
Show answer and example
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.
111. How do you prevent image out-of-memory crashes?
Show answer and example
Request sized URLs, downsample, cap concurrent decoding, set cache policy, avoid full-resolution list bitmaps and base64, and profile native bitmap memory.
112. How do you prevent stale or out-of-order search responses?
Show answer and example
Debounce for volume, but use AbortController or a latest request ID for correctness. Apply a response only when it still matches the active query.
113. How do you retry a failed Promise with exponential backoff?
Show answer and example
Loop through a bounded number of attempts, return on success, and after each retryable failure await an exponentially increasing delay before rethrowing the final error.
Example code
async function retry(fn,n=3,d=300){let e; for(let i=0;i<n;i++){try{return await fn()}catch(x){e=x; await new Promise(r=>setTimeout(r,d*2**i))}} throw e}
114. How would you structure a large React Native codebase?
Show answer and example
Organize by product domains and public interfaces; presentation depends on use cases and domain models; infrastructure implements APIs, storage, analytics, and native adapters; a design system owns primitives.
115. LRU cache design?
Show answer and example
An LRU cache evicts the least recently used item when capacity is exceeded. In JavaScript, Map preserves insertion order, so get deletes and reinserts a key to mark it recent; set removes the oldest map key when over capacity. A production cache also defines TTL, memory limits, and whether undefined is a valid value.
116. Which work runs on the JavaScript thread and which runs on the UI/main thread?
Show answer and example
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.
Output-Based JavaScript Questions
These are among the most commonly asked JavaScript and React Native output questions. Predict the result before opening the answer, then explain the execution rule rather than only stating the output.
Hoisting, Scope, and the Temporal Dead Zone
16 questions
1. Basic var hoisting?
Why: The declaration is hoisted and initialized with undefined; the assignment stays in place. What to say: Say that var is created during the execution-context creation phase. Avoid saying the complete statement physically moves.Show output and explanation
Exact output: undefined, then 10
Example code
console.log(a);
var a = 10;
console.log(a);
2. Class Temporal Dead Zone?
Why: Class declarations are not usable before their declaration is evaluated. What to say: Classes behave more like let/const than function declarations for early access: they have a Temporal Dead Zone.Show output and explanation
Exact output: ReferenceError
Example code
const user = new User();
class User {}
3. Duplicate function declarations?
Why: In the same scope, the later function declaration replaces the earlier declaration. What to say: I mention that duplicate declarations reduce readability and should be avoided even when the language permits them.Show output and explanation
Exact output: 2
Example code
console.log(getValue());
function getValue() { return 1; }
function getValue() { return 2; }
4. Function declaration hoisting?
Why: A function declaration is hoisted together with its function body. What to say: Function declarations can normally be called before their source-code position because the complete declaration is created during the creation phase.Show output and explanation
Exact output: Hello
Example code
sayHello();
function sayHello() {
console.log('Hello');
}
Source variant (react-native-javascript-output-interview-questions-2023-2026.pdf p.23):
greet();
function greet() {
console.log('Hello');
}
5. Function expression hoisting?
Why: Only the var declaration is hoisted. Its value is undefined at the call. What to say: The identifier exists because var is hoisted, but the function assignment has not happened. Calling undefined produces a TypeError.Show output and explanation
Exact output: TypeError: sayHello is not a function
Example code
sayHello();
var sayHello = function () {
console.log('Hello');
};
6. Hoisting with var?
Why: The local declaration is hoisted, but the assignment remains in its original place. What to say: JavaScript treats the function as if var x were declared at the top. It shadows the outer x, so the local value is undefined when console.log runs.Show output and explanation
Exact output: undefined
Example code
var x = 21;
function test() {
console.log(x);
var x = 20;
}
test();
7. Local var shadows outer variable?
Why: The local var is hoisted and shadows the outer count throughout the function. What to say: JavaScript resolves the nearest lexical binding. It does not fall back to the outer variable merely because the local assignment has not executed.Show output and explanation
Exact output: undefined
Example code
var count = 10;
function show() {
console.log(count);
var count = 20;
}
show();
8. Named function expression scope?
Why: The expression's name is available inside its own body, not in the surrounding scope. What to say: The internal name supports recursion and stack traces while avoiding a new outer binding.Show output and explanation
Exact output: function, then undefined
Example code
const run = function internal() {
console.log(typeof internal);
};
run();
console.log(typeof internal);
9. Parameter and var with the same name?
Why: The parameter supplies the initial local value; redeclaring it with var does not reset it. What to say: The var declaration is effectively redundant. Only the later assignment changes the parameter binding to 20.Show output and explanation
Exact output: 10, then 20
Example code
function show(value) {
console.log(value);
var value = 20;
console.log(value);
}
show(10);
10. Temporal Dead Zone?
Why: let is hoisted but cannot be accessed before its declaration is initialized. What to say: Unlike var, let and const remain in the Temporal Dead Zone from the beginning of the scope until their declaration. That is why this throws instead of printing undefined.Show output and explanation
Exact output: ReferenceError
Example code
console.log(value);
let value = 10;
11. const before declaration?
Why: const also remains in the Temporal Dead Zone until its declaration executes. What to say: const must be initialized at declaration and cannot be reassigned. Its object contents can still be mutable.Show output and explanation
Exact output: ReferenceError
Example code
console.log(apiUrl);
const apiUrl = 'example.com';
12. let before declaration?
Why: let is hoisted but remains uninitialized in the Temporal Dead Zone. What to say: Both var and let are hoisted. The difference is that var receives undefined immediately, while let cannot be read before initialization.Show output and explanation
Exact output: ReferenceError
Example code
console.log(a);
let a = 10;
13. let function expression?
Why: The let binding exists but is still in the Temporal Dead Zone. What to say: This differs from var, where calling before assignment produces a TypeError because the value is undefined.Show output and explanation
Exact output: ReferenceError
Example code
greet();
let greet = function () {
console.log('Hello');
};
14. let is block-scoped?
Why: The let binding exists only inside the if block. What to say: This is scope, not simply hoisting. The outer code has no binding named message.Show output and explanation
Exact output: ReferenceError
Example code
function test() {
if (true) {
let message = 'inside';
}
console.log(message);
}
test();
15. var function expression?
Why: The variable exists as undefined, but the function assignment has not executed. What to say: typeof returns the string 'undefined'. The next line tries to call undefined, producing a TypeError.Show output and explanation
Exact output: undefined, then TypeError
Example code
console.log(typeof greet);
greet();
var greet = function () {
console.log('Hello');
};
16. var is function-scoped?
Why: var does not create an if-block scope. What to say: var is function-scoped. let and const are block-scoped, so replacing var with let would make message unavailable outside the block.Show output and explanation
Exact output: inside
Example code
function test() {
if (true) {
var message = 'inside';
}
console.log(message);
}
test();
Arrays and Array Methods
18 questions
1. Array equality compares references?
Why: Each array literal creates a distinct object; b points to the same object as a. What to say: JavaScript does not structurally compare arrays with ===. Deep equality requires element-by-element rules.Show output and explanation
Exact output: false, then true
Example code
console.log([] === []);
const a = [];
const b = a;
console.log(a === b);
2. Chained map and filter order?
Why: map first creates [2, 4, 6, 8], then filter keeps values above 4. What to say: Method order changes both output and work. For very large data, one reduce can combine steps, but readability and profiling matter.Show output and explanation
Exact output: [6, 8]
Example code
const result = [1, 2, 3, 4]
.map(value => value * 2)
.filter(value => value > 4);
console.log(result);
3. Default sort is lexicographic?
Why: Without a comparator, sort compares string representations. What to say: For numeric ascending order I use values.sort((a, b) => a - b). I also mention that sort mutates the original array.Show output and explanation
Exact output: [1, 10, 2]
Example code
const values = [10, 2, 1];
values.sort();
console.log(values);
4. Destructuring defaults and holes?
Why: Defaults apply to undefined or a missing element, but not to null. What to say: API null and missing data can have different meanings. Destructuring preserves that distinction.Show output and explanation
Exact output: 10, null, 30
Example code
const [a = 10, b = 20, c = 30] = [undefined, null];
console.log(a, b, c);
5. Empty array conversions?
Why: An empty array converts to an empty string, which converts to zero for numeric comparison. What to say: This is a coercion puzzle, not a recommended coding pattern. I narrate ToPrimitive and numeric conversion step by step.Show output and explanation
Exact output: empty string, 0, true
6. Spread creates a shallow array copy?
Why: The array container is new, but the nested object reference is shared. What to say: For React state, copy the modified item as well: map and return a new object for the matching row.Show output and explanation
Exact output: 9
Example code
const first = [{ value: 1 }];
const second = [...first];
second[0].value = 9;
console.log(first[0].value);
7. delete leaves an array hole?
Why: delete removes the indexed property but does not shift elements or change length. What to say: Use splice for in-place removal or filter/toSpliced for a new array. Sparse arrays can behave unexpectedly with map and iteration methods.Show output and explanation
Exact output: 3, then false
Example code
const values = [10, 20, 30];
delete values[1];
console.log(values.length);
console.log(1 in values);
8. fill shares object references?
Why: fill inserts the same object reference into every position. What to say: To create independent objects I use Array.from({ length: 3 }, () => ({ count: 0 })).Show output and explanation
Exact output: [5, 5, 5]
Example code
const rows = Array(3).fill({ count: 0 });
rows[0].count = 5;
console.log(rows.map(row => row.count));
9. filter(Boolean)?
Why: Boolean removes all falsy values, not only null and undefined. What to say: This shortcut may accidentally remove valid values such as 0 or false. For nullish removal, use value => value != null.Show output and explanation
Exact output: [1, 'RN']
Example code
const values = [0, 1, '', 'RN', null, undefined, false];
console.log(values.filter(Boolean));
10. forEach return value?
Why: forEach is for side effects and always returns undefined. What to say: Use map when a transformed array is required. Returning from the callback only returns from that callback.Show output and explanation
Exact output: undefined
Example code
const result = [1, 2, 3].forEach(value => value * 2);
console.log(result);
11. includes handles NaN?
Why: indexOf uses strict-equality-like comparison; includes uses SameValueZero, which matches NaN. What to say: includes is preferable for a membership test and clearly communicates boolean intent.Show output and explanation
Exact output: -1, true
Example code
const values = [1, NaN, 3];
console.log(values.indexOf(NaN));
console.log(values.includes(NaN));
12. map callback without return?
Why: A block-bodied arrow function needs an explicit return. What to say: With concise syntax value => value * 2, the expression is returned automatically. This mistake often produces blank FlatList-derived data.Show output and explanation
Exact output: [undefined, undefined, undefined]
Example code
const result = [1, 2, 3].map(value => {
value * 2;
});
console.log(result);
13. map with an async callback?
Why: An async callback always returns a Promise, so map creates an array of Promises. What to say: To obtain values I use await Promise.all(results). map itself does not await callbacks.Show output and explanation
Exact output: true
Example code
const results = [1, 2, 3].map(async value => value * 2);
console.log(results[0] instanceof Promise);
14. map with parseInt?
Why: map supplies value, index and array. parseInt treats the index as its radix. What to say: The calls are effectively parseInt('1', 0), parseInt('2', 1), and parseInt('3', 2). I would write map(value => parseInt(value, 10)) or map(Number).Show output and explanation
Exact output: [1, NaN, NaN]
15. push return value?
Why: push mutates the array and returns its new length. What to say: This is important in React because push mutates state. I would create a new array with [...values, 4] before setting state.Show output and explanation
Exact output: 4, then [1, 2, 3, 4]
Example code
const values = [1, 2, 3];
const result = values.push(4);
console.log(result);
console.log(values);
16. reduce without an initial value?
Why: The first element becomes the initial accumulator and iteration starts at index 1. What to say: I normally provide an explicit initial value. Reducing an empty array without one throws a TypeError.Show output and explanation
Exact output: 6
Example code
const values = [1, 2, 3];
const total = values.reduce((sum, value) => sum + value);
console.log(total);
17. slice vs splice?
Why: slice returns a non-mutating copy; splice removes/replaces elements in the original. What to say: In React state updates I prefer non-mutating operations. Modern toSpliced can return a changed copy where supported.Show output and explanation
Exact output: [2, 3], [1, 2, 3, 4], [2, 3], [1, 4]
Example code
const values = [1, 2, 3, 4];
console.log(values.slice(1, 3));
console.log(values);
console.log(values.splice(1, 2));
console.log(values);
18. slice with negative indexes?
Why: slice counts negative indexes from the end; substring treats negative values as zero. What to say: I clarify the API because slice and substring differ for negative and reversed arguments.Show output and explanation
Exact output: Script, then JavaScript
Example code
const text = 'JavaScript';
console.log(text.slice(-6));
console.log(text.substring(-6));
Objects, References, and Prototypes
19 questions
1. What happens when two variables reference the same object and one mutates it?
2. Function declaration and var assignment?
Why: The function declaration initializes value first; the runtime assignment later replaces it with 10. What to say: Function declarations take precedence during initialization, but the var assignment still executes at its original line.Show output and explanation
Exact output: function, then number
Example code
console.log(typeof value);
var value = 10;
function value() {}
console.log(typeof value);
3. Getter execution?
Why: Reading an accessor property executes its getter function. What to say: A getter can hide computation or side effects behind property access. Keep getters predictable and avoid expensive work during render.Show output and explanation
Exact output: getter, then React Native
Example code
const user = {
first: 'React',
last: 'Native',
get name() {
console.log('getter');
return `${this.first} ${this.last}`;
},
};
console.log(user.name);
4. How do you flatten a nested object?
Show output and explanation
Recursively visit nested plain objects, joining path segments, and assign leaf values to the output.
Example code
function flattenObj(o,p='',out={}){for(const[k,v]of Object.entries(o)){const key=p?`${p}.${k}`:k;if(v&&typeof v==='object'&&!Array.isArray(v))flattenObj(v,key,out);else out[key]=v}return out}
5. Object dependency causes repeated effects?
Why: A new options object is created on every render. What to say: Dependencies use reference equality. I would move primitive values into the dependency list, create the object inside the effect, or memoize it when appropriate.Show output and explanation
Exact output: fetch runs after every render
Example code
const options = { page: 1 };
useEffect(() => {
console.log('fetch');
}, [options]);
6. Object keys are coerced to strings?
Why: Both object keys become the same string, '[object Object]'. What to say: Use Map when object identity must be the key. Plain-object property keys are strings or symbols.Show output and explanation
Exact output: second
Example code
const store = {};
const first = { id: 1 };
const second = { id: 2 };
store[first] = 'first';
store[second] = 'second';
console.log(store[first]);
7. Object.assign is shallow?
Why: Object.assign copies the nested reference rather than cloning it. What to say: Like object spread, Object.assign is shallow. This is important when updating nested Redux or React state.Show output and explanation
Exact output: true
Example code
const source = { settings: { dark: false } };
const copy = Object.assign({}, source);
copy.settings.dark = true;
console.log(source.settings.dark);
8. Object.freeze is shallow?
Why: The outer object is frozen, but the nested address object is not. What to say: A deep freeze must recursively freeze reachable objects. In strict mode, assigning a frozen top-level property throws.Show output and explanation
Exact output: Pune
Example code
const user = Object.freeze({
name: 'Alex',
address: { city: 'Delhi' },
});
user.address.city = 'Pune';
console.log(user.address.city);
9. Prototype property lookup?
Why: user has no own role, so lookup follows its prototype reference. What to say: Prototype lookup is dynamic. An own user.role property would shadow the prototype property.Show output and explanation
Exact output: admin, then editor
Example code
const parent = { role: 'admin' };
const user = Object.create(parent);
user.name = 'Alex';
console.log(user.role);
parent.role = 'editor';
console.log(user.role);
10. React.memo and inline object?
Why: The inline style is a new object reference, so shallow prop comparison fails. What to say: React.memo compares props shallowly. In React Native I can move static styles to StyleSheet.create. I only memoize when profiling shows meaningful render cost.Show output and explanation
Exact output: Child can log again whenever Parent renders
Example code
const Child = React.memo(({ style }) => {
console.log('child');
return <View style={style} />;
});
function Parent() {
return <Child style={{ flex: 1 }} />;
}
11. Shallow object equality?
Why: Both operators compare object identity, and these are separate objects. What to say: This reference behavior matters for React state, memoization and dependency arrays.Show output and explanation
Exact output: false, false
Example code
const a = { value: 1 };
const b = { value: 1 };
console.log(a === b);
console.log(Object.is(a, b));
12. Shallow spread copy?
Why: Spread creates a new outer object but shares nested references. What to say: Object spread is shallow. For immutable React state, I must also copy every nested level that changes, or use an immutable helper such as Immer.Show output and explanation
Exact output: Sam
Example code
const a = { user: { name: 'Alex' } };
const b = { ...a };
b.user.name = 'Sam';
console.log(a.user.name);
13. Shared object reference?
Why: a and b contain references to the same object. What to say: Assigning an object does not clone it. Mutating through either reference changes the shared object.Show output and explanation
Exact output: Rahul
Example code
const a = { name: 'Alex' };
const b = a;
b.name = 'Rahul';
console.log(a.name);
Source variant (Recent_Company_Interview_Questions_0_to_5_Years.pdf p.11):
let a = {}; let b = a; b.name = 'RN'; console.log(a.name); // 'RN'
14. What happens when a method is detached from its object?
Show output and explanation
The receiver is lost, so a strict-mode call has this as undefined; accessing instance data fails or yields no expected value depending on the function body and environment.
Example code
const obj={name:'React',show(){console.log(this?.name)}}; const fn=obj.show; fn(); // undefined
15. What is the output when a property exists only on the prototype?
16. const object mutation?
Why: const prevents rebinding, not mutation of the referenced object. What to say: I cannot assign a new object to user, but I can change its properties unless it is frozen. const does not mean immutable.Show output and explanation
Exact output: Sam
Example code
const user = { name: 'Alex' };
user.name = 'Sam';
console.log(user.name);
17. delete reveals a prototype value?
Why: Deleting the own property exposes the inherited property during the next lookup. What to say: delete affects own configurable properties; it does not delete a similarly named prototype property.Show output and explanation
Exact output: 2, then 1
Example code
const parent = { value: 1 };
const child = Object.create(parent);
child.value = 2;
console.log(child.value);
delete child.value;
console.log(child.value);
18. in vs own property?
Why: in checks the prototype chain; Object.hasOwn checks only the object itself. What to say: When validating data records, own-property checks often avoid accidentally accepting inherited values.Show output and explanation
Exact output: true, then false
Example code
const parent = { role: 'admin' };
const user = Object.create(parent);
user.name = 'Alex';
console.log('role' in user);
console.log(Object.hasOwn(user, 'role'));
19. useCallback reference stability?
Why: useCallback returns the same function while dependencies are equal. What to say: useCallback does not stop the function body from running and is not automatically a performance win. It is useful when reference equality matters, such as a memoized child.Show output and explanation
Exact output: The function reference stays stable until count changes
Example code
const onPress = useCallback(() => {
console.log(count);
}, [count]);
Type Coercion, Equality, and Truthiness
11 questions
1. What does typeof null return?
2. Boolean arithmetic?
Why: Numeric conversion maps true to 1 and false to 0. What to say: I avoid clever boolean arithmetic in production because explicit intent is easier to maintain.Show output and explanation
Exact output: 2, 1, 0
3. Loose vs strict equality?
Why: Loose equality performs type coercion; strict equality requires matching types. What to say: Use strict equality by default. If discussing loose equality, explain the conversion rather than memorizing the result.Show output and explanation
Exact output: true, false, true, false
4. NaN equality?
Why: NaN is unequal to every value under ===, including itself. What to say: Use Number.isNaN to test NaN without coercing unrelated values. Object.is also recognizes NaN as the same value.Show output and explanation
Exact output: false, true, true
5. String addition vs numeric subtraction?
Why: The + operator concatenates when a string is involved; subtraction converts operands to numbers. What to say: I evaluate left to right: 5 + '2' becomes '52', then '52' - 1 becomes 51. Explicit conversion is safer for TextInput values.Show output and explanation
Exact output: 52, 3, 51
6. String plus number coercion?
Why: + concatenates when one operand is a string; subtraction performs numeric coercion. What to say: I avoid relying on implicit coercion in application code and convert inputs explicitly with Number or parsing plus validation.Show output and explanation
Exact output: 52, 3, 7
7. Truthiness of string values?
Why: Every non-empty string and every object is truthy. What to say: A TextInput containing 'false' is still a truthy string. Parse user or API values according to their schema.Show output and explanation
Exact output: true, true, false, true
8. What is the result of [] == false?
Show output and explanation
It is true: the array converts to an empty string and then 0, while false converts to 0.
9. null and undefined arithmetic?
Why: Numeric conversion turns null into 0 and undefined into NaN. What to say: This is a common reason calculations from incomplete API data become NaN. Validate values before arithmetic.Show output and explanation
Exact output: 1, NaN, 0, NaN
10. null compared with undefined?
Why: Loose equality has a special rule making null equal to undefined; strict equality distinguishes them. What to say: This is one of the few predictable loose-equality pairs, but explicit nullish checks are clearer.Show output and explanation
Exact output: true, false
11. typeof null?
Why: This is a historical JavaScript language quirk. What to say: null is a primitive nullish value despite typeof returning 'object'.Show output and explanation
Exact output: 'object'
Closures, Functions, and this
12 questions
1. Arrow function and arguments?
Why: Arrow functions do not create their own arguments object; they capture the surrounding one. What to say: Use rest parameters when an arrow needs its own variable arguments. Arrow functions also capture this lexically.Show output and explanation
Exact output: outer
Example code
function outer() {
const arrow = () => console.log(arguments[0]);
arrow('inner');
}
outer('outer');
2. Closure counter?
Why: The returned function retains access to its lexical environment. What to say: This is a closure. count stays private but remains alive because the returned function references it. Closures are useful for custom hooks, debounce functions and encapsulation.Show output and explanation
Exact output: 1, 2
Example code
function counter() {
let count = 0;
return () => ++count;
}
const next = counter();
console.log(next());
console.log(next());
3. Closure with let in a loop?
4. Closure with var in a loop?
Why: All callbacks close over the same function-scoped variable. What to say: By the time the timers execute, the loop has finished and the shared i is 3. I can fix it with let, an IIFE, or by passing the value to another function.Show output and explanation
Exact output: 3, 3, 3
Example code
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
5. Empty dependency stale closure?
Why: The effect callback captures count from the first render. What to say: The empty array means the effect does not resubscribe when count changes. Depending on the goal, I would add count, use a ref for the latest value, or use a functional update.Show output and explanation
Exact output: It repeatedly logs the initial count
Example code
useEffect(() => {
const id = setInterval(() => console.log(count), 1000);
return () => clearInterval(id);
}, []);
Source variant (Recent_Company_Interview_Questions_0_to_5_Years.pdf p.5):
// Bug: always logs initial count
useEffect(() => {
const id = setInterval(() => console.log(count), 1000);
return () => clearInterval(id);
}, []); // missing count
6. Function closure after return?
Why: inner retains the lexical environment of the completed outer call. What to say: This is a closure, not hoisting. The binding remains alive because the returned function references it.Show output and explanation
Exact output: 1, then 2
Example code
function outer() {
let value = 1;
return function inner() {
console.log(value++);
};
}
const next = outer();
next();
next();
7. Function length?
Why: Function length counts parameters before the first default and excludes the rest parameter. What to say: Libraries sometimes use function arity, but default/rest parameters make it an imperfect signal.Show output and explanation
Exact output: 3, 1, 0
Example code
function first(a, b, c) {}
function second(a, b = 2, c) {}
function third(...args) {}
console.log(first.length, second.length, third.length);
8. Regular method vs arrow this?
Why: A regular method receives the calling object as this. An arrow captures lexical this. What to say: I would mention that the second value depends on the surrounding module/runtime. Arrow functions do not dynamically bind this, so they are usually unsuitable as object methods when the object is needed.Show output and explanation
Exact output: Alex, then usually undefined
Example code
const user = {
name: 'Alex',
regular() { console.log(this.name); },
arrow: () => console.log(this.name),
};
user.regular();
user.arrow();
9. Rest parameters?
Why: The rest parameter collects remaining arguments into a real array. What to say: Unlike the older arguments object, rest is an array and works naturally with array methods.Show output and explanation
Exact output: 1, then [2, 3, 4]
Example code
function inspect(first, ...rest) {
console.log(first);
console.log(rest);
}
inspect(1, 2, 3, 4);
10. What is function composition, and how do compose and pipe differ?
11. What is the output of a closure counter called three times?
12. call, apply and bind?
Why: call invokes with separate arguments, apply invokes with an array-like list, and bind returns a function. What to say: All three control this for a normal function. bind also supports partial application and does not execute immediately.Show output and explanation
Exact output: Alex-Delhi, Alex-Pune, Alex-Noida
Example code
function intro(city) {
return `${this.name}-${city}`;
}
const user = { name: 'Alex' };
console.log(intro.call(user, 'Delhi'));
console.log(intro.apply(user, ['Pune']));
console.log(intro.bind(user, 'Noida')());
Promises, async/await, and the Event Loop
17 questions
1. Async function return value?
Why: An async function always returns a Promise fulfilled with its returned value. What to say: If it throws, the returned Promise rejects. This is why callers must await it or handle the Promise.Show output and explanation
Exact output: true, then 42
Example code
async function getValue() {
return 42;
}
console.log(getValue() instanceof Promise);
getValue().then(console.log);
2. Event loop: Promise vs timer?
Why: Synchronous code runs first, then microtasks, then timer tasks. What to say: The Promise callback is a microtask, while setTimeout schedules a task. After the call stack is empty, JavaScript drains microtasks before processing the timer queue.Show output and explanation
Exact output: A, D, C, B
Example code
console.log('A');
setTimeout(() => console.log('B'), 0);
Promise.resolve().then(() => console.log('C'));
console.log('D');
3. Multiple Promise microtasks?
Why: Promise callbacks are queued in registration order after synchronous code. What to say: Both callbacks enter the microtask queue. The queue is FIFO, so p1 runs before p2.Show output and explanation
Exact output: start, end, p1, p2
4. Nested Promise microtasks?
Why: The inner Promise callback is queued before the next chained reaction becomes runnable. What to say: Walk through the microtask queue after each callback. Do not answer only by saying 'Promises run first'; explain their registration order.Show output and explanation
Exact output: 1, 2, 3
5. Promise chain values?
Why: Each then receives the value returned by the previous callback. What to say: Returning a normal value resolves the next Promise with that value. Returning a Promise would make the chain wait for it.Show output and explanation
Exact output: 2, 4
Example code
Promise.resolve(1)
.then(v => v + 1)
.then(v => {
console.log(v);
return v * 2;
})
.then(console.log);
6. Promise error recovery?
Why: catch handles the rejection and returns a fulfilled value to the next then. What to say: A catch can recover the chain. If I throw again inside catch, the following Promise remains rejected.Show output and explanation
Exact output: error, recovered
Example code
Promise.reject('error')
.catch(value => {
console.log(value);
return 'recovered';
})
.then(console.log);
7. Promise executor is synchronous?
Why: The Promise constructor executes immediately. The then callback is a microtask. What to say: Say that creating a Promise does not automatically defer its executor. This matters when a React Native Promise wrapper performs expensive synchronous work.Show output and explanation
Exact output: 1, 2, 4, 3
Example code
console.log(1);
new Promise(resolve => {
console.log(2);
resolve();
}).then(() => console.log(3));
console.log(4);
8. Promise.race?
Why: race settles with the first input to settle, not the first item in array order. What to say: I mention that race can reject as well. It does not cancel the losing operations, so API cancellation needs AbortController or another mechanism.Show output and explanation
Exact output: fast
9. Throwing inside then?
Why: An exception in a then callback rejects the Promise returned by that then. What to say: Promise chains convert synchronous callback exceptions into rejections, allowing a later catch to handle them.Show output and explanation
Exact output: data, caught
10. Timer callback creates a microtask?
Why: After each timer task, JavaScript drains newly queued microtasks before the next timer task. What to say: Relate this to React Native: long JS work delays timers, gestures and state-update processing because they share the JavaScript thread.Show output and explanation
Exact output: start, end, timer 1, promise, timer 2
Example code
console.log('start');
setTimeout(() => {
console.log('timer 1');
Promise.resolve().then(() => console.log('promise'));
}, 0);
setTimeout(() => console.log('timer 2'), 0);
console.log('end');
11. What does an async function return?
12. What is the output of synchronous logs, Promise.then, and setTimeout(0)?
13. What is the output when Promise.then and queueMicrotask are queued before a timer?
Show output and explanation
It prints A, E, C, D, B. Synchronous logs run first; Promise.then and queueMicrotask then run in enqueue order; the timer runs afterward.
14. async/await ordering?
Why: The function runs synchronously until await. Its continuation is a microtask. What to say: Calling an async function does not make everything inside it delayed. Code before await is synchronous; code after await resumes in the microtask queue.Show output and explanation
Exact output: 3, 1, 4, 2
Example code
async function run() {
console.log(1);
await Promise.resolve();
console.log(2);
}
console.log(3);
run();
console.log(4);
15. await with a non-Promise value?
Why: await behaves like awaiting Promise.resolve(10), so continuation is asynchronous. What to say: Even an already available value causes the code after await to resume in a later microtask.Show output and explanation
Exact output: A, C, B
Example code
async function run() {
console.log('A');
await 10;
console.log('B');
}
run();
console.log('C');
16. catch recovers a Promise chain?
Why: Returning from catch fulfills the next Promise. What to say: A catch is not always the end of a chain. To keep it rejected, I must throw or return a rejected Promise.Show output and explanation
Exact output: failed, recovered
Example code
Promise.reject('failed')
.catch(error => {
console.log(error);
return 'recovered';
})
.then(console.log);
17. finally does not replace a value?
Why: A normal return from finally does not replace the settled value. What to say: finally is for cleanup. It passes through the original value unless it throws or returns a rejected Promise.Show output and explanation
Exact output: data
React and React Native Output Behavior
16 questions
1. Changing key resets state?
Why: Changing the key makes React treat it as a different component instance. What to say: The old Profile unmounts and a new one mounts. Keys control identity, not just list warnings, and can intentionally reset state.Show output and explanation
Exact output: A changed userId resets Profile's local state
Example code
<Profile key={userId} userId={userId} />
2. Controlled vs uncontrolled components?
Show output and explanation
A controlled input receives its value from React state and reports changes back, which makes validation and reset predictable. An uncontrolled input keeps its own value and is read through a ref. I prefer controlled React Native forms for most cases, but a form library may use refs internally to reduce re-renders in very large forms.
3. Effect cleanup order?
Why: React cleans up the previous effect before running the replacement. What to say: Each cleanup closes over values from its own render. Cleanup prevents leaked timers, subscriptions and listeners.Show output and explanation
Exact output: For 0 to 1: effect 0, cleanup 0, effect 1
Example code
useEffect(() => {
console.log('effect', count);
return () => console.log('cleanup', count);
}, [count]);
4. FlatList and extraData?
Why: FlatList behaves like a PureComponent and may skip work when its relevant props remain shallow-equal. What to say: I would pass extraData={selectedId}, keep renderItem dependencies correct, and update data immutably. I would not disable virtualization to force rendering.Show output and explanation
Exact output: Rows may not update when only selectedId changes
Example code
<FlatList
data={items}
renderItem={({ item }) => (
<Row item={item} selected={selectedId === item.id} />
)}
/>
5. Functional state updates?
Why: React applies each updater to the result of the previous queued updater. What to say: Functional updates avoid stale captured state and are the correct choice when calculating from previous state.Show output and explanation
Exact output: After one press, count is 3
Example code
setCount(c => c + 1);
setCount(c => c + 1);
setCount(c => c + 1);
6. Heavy JavaScript work and UI?
Why: Heavy synchronous work blocks the JavaScript thread and delays event handling and React updates. What to say: I would first profile. Then I might reduce the work, process it in chunks, defer non-urgent work, or move CPU-heavy processing to a native/JSI worker solution. async/await alone does not move CPU work off the JS thread.Show output and explanation
Exact output: The app can freeze or drop frames until the loop finishes
Example code
const press = () => {
const result = expensiveSynchronousLoop();
setResult(result);
};
7. Lazy state initializer?
Why: React calls the initializer to create initial state, not on every ordinary re-render. What to say: The function form avoids repeating expensive initialization. Development Strict Mode may call it more than once to verify purity, so the initializer must have no side effects.Show output and explanation
Exact output: Normally initialize prints only on mount
Example code
const [value] = useState(() => {
console.log('initialize');
return expensiveCalculation();
});
8. Logging immediately after setState?
Why: The handler continues using state from the render that created it. What to say: A state setter schedules another render; it does not mutate the current count variable. To observe the committed value, I can log during render or in an effect dependent on count.Show output and explanation
Exact output: The first press logs 0
Example code
const [count, setCount] = useState(0);
const press = () => {
setCount(1);
console.log(count);
};
9. Mutating React state?
Why: The setter receives the same object reference, so React can consider the state unchanged. What to say: React state should be treated as immutable. I would write setUser(previous => ({ ...previous, name: 'Sam' })) so React receives a new reference.Show output and explanation
Exact output: A re-render may be skipped
Example code
const [user, setUser] = useState({ name: 'Alex' });
const press = () => {
user.name = 'Sam';
setUser(user);
};
10. Pure function and side effects?
Show output and explanation
A pure function returns the same output for the same inputs and does not mutate external state. Side effects include network calls, storage, logging, timers, and mutation. Redux reducers must be pure. I keep calculations pure and isolate effects in hooks, middleware, or service functions because pure code is easier to test and reason about.
11. Render and effect order?
Why: The component renders first; the passive effect runs after commit. What to say: Rendering must stay pure. Side effects such as subscriptions and requests belong in useEffect. In development Strict Mode, React can intentionally repeat this lifecycle.Show output and explanation
Exact output: Production: render, effect
Example code
function App() {
console.log('render');
useEffect(() => console.log('effect'), []);
return <Text>Hello</Text>;
}
12. Repeated direct state updates?
Why: All calls calculate the next value from count captured by the current render. What to say: React batches the updates. These do not mean 'increment three times'; they all request the value 1. When next state depends on previous state, I use the functional updater.Show output and explanation
Exact output: After one press, count is 1
Example code
const [count, setCount] = useState(0);
const press = () => {
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
};
13. ScrollView vs FlatList output behavior?
Why: ScrollView renders all children rather than virtualizing a large dataset. What to say: For a large or unbounded list I use FlatList or FlashList so only a window of items is mounted. Then I profile keyExtractor, getItemLayout, windowSize and row memoization.Show output and explanation
Exact output: All mapped rows are created immediately
Example code
<ScrollView>
{items.map(item => <Row key={item.id} item={item} />)}
</ScrollView>
14. Strict Mode console output?
Why: Strict Mode repeats selected work in development to expose impure rendering and missing cleanup. What to say: I would not solve duplicate development logs by removing Strict Mode. I would make rendering and effects idempotent and verify production behavior separately.Show output and explanation
Exact output: Development may print render twice; production normally once
Example code
function Profile() {
console.log('render');
return <Text>Profile</Text>;
}
15. useMemo dependencies?
Why: useMemo reuses its cached value while dependencies remain equal by Object.is. What to say: I use it for expensive calculations, not for correctness. Mutating the existing items array is a bug because the reference would not change and the cached result could become stale.Show output and explanation
Exact output: calculate runs on mount and when the items reference changes
Example code
const total = useMemo(() => {
console.log('calculate');
return items.reduce((sum, x) => sum + x.price, 0);
}, [items]);
16. Guidelines you follow while writing code?
Show output and explanation
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.
More Frequently Asked Output Questions
11 questions
1. Default parameter scope?
Why: The parameter's own uninitialized binding shadows the outer value in the default-expression scope. What to say: Default parameters have their own scope. The right-hand value refers to the parameter currently in its TDZ, not the outer variable.Show output and explanation
Exact output: ReferenceError
Example code
let value = 5;
function show(value = value) {
return value;
}
show();
2. Destructuring defaults?
Why: A default value is used only when the property is undefined. What to say: null is an explicit value, so a remains null. b is undefined, so its default value 20 is applied.Show output and explanation
Exact output: null, 20
Example code
const { a = 10, b = 20 } = {
a: null,
b: undefined,
};
console.log(a, b);
3. OR vs nullish coalescing?
Why: || falls back for all falsy values; ?? only for null or undefined. What to say: I use ?? when zero, false or an empty string are valid values. It avoids incorrectly replacing valid falsy data.Show output and explanation
Exact output: 100, 0, 100
4. Optional chaining?
Why: Optional chaining stops safely at null/undefined; ?? supplies the fallback. What to say: This avoids a property-access error. I still use it carefully because excessive optional chaining can hide unexpected API-data problems.Show output and explanation
Exact output: undefined, Guest
Example code
const user = null;
console.log(user?.profile?.name);
console.log(user?.profile?.name ?? 'Guest');
5. Ref updates?
Why: A ref persists between renders, but changing current does not cause a render. What to say: I use refs for mutable values that do not affect UI, such as timer IDs or previous values. Visible data should normally be state.Show output and explanation
Exact output: It increases once for each render
Example code
const renders = useRef(0);
renders.current += 1;
console.log(renders.current);
6. Strings are immutable?
Why: Assigning to a string index does not modify the string value. What to say: String methods return new strings. In strict contexts, assigning to a read-only indexed property may throw rather than silently doing nothing.Show output and explanation
Exact output: React
Example code
let text = 'React';
text[0] = 'X';
console.log(text);
7. What is the output of var versus let in a loop with setTimeout?
Show output and explanation
var produces 3,3,3 because all callbacks share one function-scoped binding after the loop. let produces 0,1,2 because each iteration gets a new binding.
Example code
for(var i=0;i<3;i++)setTimeout(()=>console.log(i)); // 3 3 3
for(let i=0;i<3;i++)setTimeout(()=>console.log(i)); // 0 1 2
8. What is the result of [] + []?
Show output and explanation
It is an empty string because both arrays convert to empty strings and + performs string concatenation.
9. What is the result of {} + []?
Show output and explanation
The result is parsing-context dependent: leading {} may be parsed as a block, while parenthesized objects convert to '[object Object]'. Never rely on this ambiguity.
10. replace changes only the first string match?
Why: A string search in replace affects only the first occurrence; replaceAll affects all. What to say: A global regular expression is another option. Strings remain unchanged because both methods return new values.Show output and explanation
Exact output: RN JS JS, then RN RN RN
Example code
const text = 'JS JS JS';
console.log(text.replace('JS', 'RN'));
console.log(text.replaceAll('JS', 'RN'));
11. var vs let in loop?
Why: var shares one function-scoped binding; let creates a binding per iteration. What to say: Timer callbacks run after the loops, so closure binding semantics determine the values.Show output and explanation
Exact output: var prints 3, 3, 3; let prints 0, 1, 2.
Example code
for (var i = 0; i < 3; i++) setTimeout(() => console.log(i)); // 3 3 3
for (let i = 0; i < 3; i++) setTimeout(() => console.log(i)); // 0 1 2
Scenario-Based Questions
51 questions
1. A component continues updating after the user leaves the screen?
Show answer and example
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. A deep link opens the wrong screen when the app starts from a killed state?
Show answer and example
I log the raw initial URL, React Navigation linking parse result, restored auth state, and restored navigation state. I process the initial link once, validate params, and wait for auth hydration before navigating. If the route is protected I store it as a pending destination, complete login, then reset/navigate. I test custom schemes and universal links separately.
3. A screen makes the same API call three times after navigation. How do you investigate?
Show answer and example
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. Context causes input lag in a large form?
Show answer and example
A changing Provider value notifies every consumer, so one Context containing fifteen fields can re-render the whole form per keystroke. I keep field state local or use React Hook Form with field subscriptions, split stable contexts, and memoize Provider values. Context is dependency distribution, not automatically an efficient high-frequency store.
5. FlatList scrolling is janky only on low-end Android devices. What do you do?
Show answer and example
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.
Example code
<FlatList data={items} keyExtractor={item => item.id} renderItem={renderItem} windowSize={7} removeClippedSubviews />
Profile before changing windowing props; stabilize renderItem and row props first.
6. How do you protect code from a third-party function that mutates inputs?
Show answer and example
Pass an appropriate clone at the boundary, freeze values in development to detect mutation, and document ownership. structuredClone is suitable only for supported data.
7. Images crash Android with OutOfMemoryError?
Show answer and example
I check source dimensions and decoded bitmap memory, because a compressed file can still decode into a huge bitmap. I request server-sized thumbnails, avoid base64, limit concurrent image loads, use a maintained cache library, and keep FlatList windows reasonable. I inspect Android memory and image cache behavior and never solve it by simply increasing the heap.
8. Push notifications work in debug but not in release?
Show answer and example
I verify production APNs credentials, release bundle id/package name, provisioning entitlements, Firebase service files for the correct flavor, Android notification permission and channels, and R8 keep rules for the notification SDK. I test an installed release build with the app foreground, background, and killed, and inspect native device logs and provider delivery reports.
9. Reducers and scenario-based Redux questions?
Show answer and example
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.
10. Redux updates cause the whole app to re-render?
Show answer and example
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.
11. S2. TextInput is hidden behind the keyboard on Android?
Show answer and example
"I verify android:windowSoftInputMode is adjustResize, use KeyboardAvoidingView or react-native-keyboard-controller, and test edge-to-edge/insets on newer Android versions. Nested ScrollViews often cause this, so I simplify layout and retest on a real device."
12. S3. Images cause OutOfMemoryError on Android?
Show answer and example
"I never load full-resolution images into long lists. I request sized URLs, compress assets, use a caching image library, limit concurrent decodes, and recycle bitmaps carefully. OOM is usually too many large bitmaps at once."
13. S4. Push works in foreground but not when app is killed?
Show answer and example
I verify FCM and APNs credentials for the correct environment, bundle/package identifiers, Android channels, payload type, iOS entitlements, provisioning, and Background Modes. I test a fully killed release build on a real device because foreground JavaScript handlers are not sufficient for terminated state.
14. S5. Screen re-renders every second with no visible change?
Show answer and example
"I use React DevTools or why-did-you-render to see what changed. Common causes are a timer calling setState, a Context Provider recreating its value object every render, parent animation state, or navigation focus listeners writing state repeatedly. I stabilize the provider value and remove unnecessary setState." Page 12/18
15. Senior Git scenarios: conflict, wrong commit, revert, and cherry-pick?
Show answer and example
For conflicts I understand both changes, resolve locally, run tests, and continue the merge/rebase. To undo a published change I use git revert because it preserves history. I use reset only for local unshared history. cherry-pick copies a focused commit to a release/hotfix branch. I use force-with-lease only on my own branch with team awareness, never casually on main.
16. Senior navigation scenarios?
Show answer and example
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.
17. The app freezes while parsing a very large API response?
Show answer and example
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.
18. Token refresh creates an infinite 401 loop?
Show answer and example
I mark retried requests so each request retries only once, exclude the refresh endpoint from the interceptor, and use one shared refresh Promise for parallel 401s. If refresh fails or returns 401, I clear credentials and reset to login. I also check clock skew, token audience, and whether the retried request actually receives the new token.
19. Users report memory increasing every time they open and close a screen?
Show answer and example
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.
20. Why can Promise and setTimeout logs appear in an unexpected order?
Show answer and example
Synchronous code runs first, then queued microtasks, then timer macrotasks. Nested scheduling adds new work to the relevant queue, so reason in enqueue order rather than timer delay alone.
21. Why might a Promise chain stop unexpectedly?
Show answer and example
Likely causes include an unhandled rejection, a missing return from then, an error swallowed in catch, or a forgotten await. Trace settlement and ensure every branch returns or throws deliberately.
22. onEndReached fires multiple times and duplicates pagination data. How do you fix it?
Show answer and example
I add an isFetchingNextPage guard, track whether more data exists, and deduplicate records by stable id. I avoid changing the data reference unnecessarily during momentum and can use onMomentumScrollBegin when the UX requires it. With React Query I use fetchNextPage and its built-in isFetchingNextPage flag. The backend should preferably use cursor pagination so repeated requests are idempotent.
23. A CodePush/OTA update crashes only one native app version?
Show answer and example
The JS bundle is incompatible with that installed native binary. I configure runtime or binary version targeting, stop the rollout, roll back the OTA, and inspect which native API changed. OTA bundles must declare compatible native versions and be tested against every targeted binary. Native dependency or permission changes require a store release, not CodePush.
24. A Reanimated animation is smooth, but pressing a button during it responds late?
Show answer and example
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.
25. A native SDK works in debug but crashes in the release build?
Show answer and example
On Android I inspect R8/ProGuard keep rules, missing transitive dependencies, ABI packaging, initialization order, and obfuscated stack traces using mapping.txt. On iOS I inspect framework embedding/signing, architecture slices, linker flags, dSYM symbolication, and release-only optimization assumptions. I reproduce the exact signed release binary and compare native logs.
26. A third-party library blocks migration to the New Architecture?
Show answer and example
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.
27. How do you debug memory leaks after navigating screens?
Show answer and example
I reproduce by navigating back and forth while watching memory. Common causes are uncleared timers, event listeners, native emitters, sockets, or closures holding large arrays. I verify every useEffect has cleanup, remove NativeEventEmitter subscriptions, and use Xcode Instruments or Android Profiler plus Hermes heap tools. If memory only goes up and never drops, it is a leak.
28. How do you design secure authentication with refresh, biometrics, and session expiry?
Show answer and example
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.
29. How do you diagnose a FlatList that freezes while scrolling?
Show answer and example
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.
30. How do you handle a third-party SDK that does not support the New Architecture?
Show answer and example
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.
31. How do you handle expensive computation that blocks the JavaScript thread?
Show answer and example
Chunk interruptible work, defer noncritical tasks, move justified compute to a threaded native or C++ module, and keep UI math in worklets.
32. How do you handle multithreading in React Native?
Show answer and example
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.
33. How do you investigate an 8–10 second app launch?
Show answer and example
Break launch into native startup, bundle load, React init, first paint, and interactive time. Defer noncritical SDKs, imports, parsing, and storage, then measure again.
34. How do you prevent TextInput from being hidden by the keyboard on Android?
Show answer and example
Use correct insets, KeyboardAvoidingView or a keyboard controller, verify adjustResize, and test edge-to-edge behavior with gesture navigation.
35. How do you prevent expensive re-renders?
Show answer and example
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.
36. How should exponential-backoff retries be designed?
Show answer and example
Use bounded attempts, exponential delays with jitter and a maximum cap, honor server retry hints, and retry only transient and safe/idempotent operations.
37. How would you diagnose a page becoming unresponsive after processing a large dataset?
Show answer and example
Profile to confirm synchronous CPU work, then reduce complexity, virtualize rendered data, and chunk, defer, or move computation off the critical thread.
38. How would you investigate a memory leak that grows over hours?
Show answer and example
Take repeated heap snapshots, reproduce lifecycle cycles, inspect growing retainers such as timers, listeners, caches, and native subscriptions, then verify cleanup stops growth.
39. How would you migrate a legacy application to the New Architecture?
Show answer and example
Upgrade incrementally, baseline crashes and performance, inventory libraries, replace abandoned dependencies, migrate custom specs, establish release E2E coverage, and stage the rollout with flags.
40. How would you optimize an app with rising memory, slow renders, and long synchronous tasks?
Show answer and example
Profile each symptom separately, fix retained resources, virtualize large lists, reduce hot re-renders, memoize measured bottlenecks, and split or move long synchronous work.
41. How would you safely adopt React 19 in an existing React Native application?
Show answer and example
Start from the React version supported by the selected React Native release rather than upgrading React independently. Audit native libraries, navigation, testing tools, custom render behavior, and deprecated APIs; then upgrade on a branch, run Android and iOS regression suites, profile startup and rendering, and use a staged rollout. Keep a rollback path until crash-free sessions and business journeys are stable.
42. How would you safely process 10,000 API requests?
Show answer and example
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.
43. Offline users create conflicting edits that sync later?
Show answer and example
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.
44. Production crashes increased after a staged release. What actions do you take?
Show answer and example
I compare crash-free users and ANRs by app version, OS, device, and affected flow. I symbolicate with uploaded source maps, dSYMs, and mapping files, then identify whether the regression is JS or native. I pause the rollout, roll back an OTA if compatible, prepare a hotfix, add a regression test, and monitor the fixed cohort before resuming rollout. Communication and impact assessment are part of the response.
45. Responsive UI vs response UI?
Show answer and example
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.
46. Service workers and how they relate to React Native?
Show answer and example
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.
47. The app is slow. Walk through your investigation?
Show answer and example
I first define the symptom: startup, navigation, scrolling, input, network, or memory. I reproduce in release mode and inspect JS/UI FPS, React renders, Hermes CPU, native traces, network timing, images, and memory. I form one hypothesis, change one bottleneck, compare metrics, and add a regression guard. I never begin by adding memoization everywhere.
48. The app's startup time changed from 2 seconds to 8 seconds after adding SDKs?
Show answer and example
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.
49. Why do push notifications work in foreground but not when the app is terminated?
Show answer and example
Verify APNs or FCM credentials, entitlements, payload type, native killed-state handlers, Android channels and OEM restrictions, and test the signed release build.
50. Why does a screen re-render every second with no visible state change?
Show answer and example
Highlight updates and inspect timers, provider values, parent animation state, selectors, and navigation focus listeners that schedule state repeatedly.
51. Why does memory grow when navigating between screens?
Show answer and example
Repeated navigation can expose uncleared subscriptions, timers, retained screens, image caches, global listeners, and closures holding large data. Compare snapshots after GC.
HR & Behavioral Questions
5 questions
1. How do you handle disagreement on architecture?
Show answer and example
Restate constraints and success criteria, compare trade-offs, migration, failure modes, and reversibility, time-box evidence-gathering, record the ADR and revisit trigger, then support the decision.
2. How do you lead a performance improvement across a team?
Show answer and example
Turn 'slow' into agreed metrics and representative devices, baseline, assign bottleneck ownership, review traces, set budgets, prioritize user impact, and encode proven patterns in shared components.
3. How do you mentor engineers while maintaining delivery speed?
Show answer and example
Match support to risk and experience through pairing, examples, bounded ownership, and reasoning-focused reviews; protect feedback time and remove recurring friction with tooling and docs.
4. Tell me about a production incident—how should a senior answer?
Show answer and example
Use a quantified situation, detection and containment, evidence-based cause, communication, and durable prevention. Separate the trigger from systemic contributors and state the learning.
5. What do you look for in code review as a senior engineer?
Show answer and example
Review correctness, cancellation and failure paths, state ownership, security, privacy, accessibility, realistic performance, tests, native lifecycle, and observability; separate blockers from suggestions and explain why.
Final interview advice
Memorizing definitions is not enough. A strong answer usually follows this order:
- State the rule or definition clearly.
- Explain the important behavior or trade-off.
- Walk through a small code or production example.
- Mention the main failure mode or edge case.
- For senior questions, explain how you would measure, test, or safely roll out the solution.
If this guide helped you, save it for revision and share the topic you found most challenging in the comments.
Top comments (0)