Top 30 React Native Interview Questions and Answers
30 multiple-choice questions on React Native, of the kind that come up in a technical interview, drawn from 30 bites in the React Native library. Answer them here or read straight down. Every question carries the correct option, why it is correct, and a link to the bite it came from.
React Native, Expo, native modules, cross-platform
30 questions. Pick an answer, or open “Show the answer” to read it.
Answers are graded in your browser. Nothing is saved, and no XP or streak is earned here. The app keeps score.
Question 1 of 30
A team needs a niche third-party native SDK that has no Expo support yet wants EAS builds and OTA updates. What is the most accurate take?
Show the answer
Answer: a · They can use Expo prebuild with a config plugin to integrate the SDK while keeping EAS and OTA
Expo prebuild plus a config plugin lets you add arbitrary native code while retaining EAS Build and EAS Update. Abandoning Expo is unnecessary, and Expo Go actually cannot load custom native modules, which is the reverse of the distractor's claim.
Read the full bite: Expo managed workflow vs bare React Native
Question 2 of 30
Why does a 200ms synchronous data mapping on a React Native screen freeze interactive components like TouchableOpacity?
Show the answer
Answer: b · It monopolizes the JavaScript thread, so batched native updates and queued touch events cannot be processed.
The correct answer recognizes that the JavaScript thread is blocked, preventing batched native updates and touch events from being handled. Option A is tempting because it confuses the JavaScript thread with the native UI main thread, which is the exact misconception the card highlights.
Read the full bite: UI unresponsive during large data processing on main thread
Question 3 of 30
What is the primary effect of enabling inline requires in a React Native app?
Show the answer
Answer: a · It defers a module's evaluation until the first time it is actually used
Inline requires transform top-level imports so a module is evaluated lazily on first use, cutting startup work. It does not compile to machine code (that is closer to Hermes bytecode) nor perform tree shaking, which is a separate bundler concern.
Question 4 of 30
When a native module method reads a live device value to return to JavaScript, why should it use a Promise or callback rather than a direct return?
Show the answer
Answer: d · Because crossing the native-to-JS boundary is asynchronous, so results are delivered via promise or callback
Values crossing from native into JavaScript are delivered asynchronously, so a Promise or callback is the correct pattern. Native code can return constants synchronously via getConstants, and package registration is unrelated to whether methods are async.
Question 5 of 30
Why can defining styles with StyleSheet.create be preferable to inline literal objects in a long list?
Show the answer
Answer: c · It reuses a stable object reference across renders instead of allocating a new object each time
StyleSheet styles are created once and referenced by key, giving stable references that avoid per-render allocations. React Native has no CSS cascade, and unit handling is not what StyleSheet.create provides.
Question 6 of 30
What is the key behavioral difference between nesting Text inside Text versus nesting components inside a View?
Show the answer
Answer: c · Text inside Text inherits text styles like color and fontSize, while View children do not inherit styles
Nested Text inherits text style properties from its parent Text, which is unique to text rendering. View does not propagate styles to its children, so each child View is styled independently.
Question 7 of 30
In React Native, what is the default flexDirection, and how does it compare to the web?
Show the answer
Answer: d · Default is column, which differs from the web's default of row
React Native defaults flexDirection to column, so children stack vertically, whereas standard CSS on the web defaults to row. The other options misstate both the React Native default and the web comparison.
Read the full bite: Default flexDirection and header-content-footer layout
Question 8 of 30
For a parent View with flexDirection column, which statement about alignItems and justifyContent is correct?
Show the answer
Answer: a · justifyContent aligns children along the vertical main axis and alignItems along the horizontal cross axis
With column direction the main axis is vertical, so justifyContent governs vertical placement and alignItems governs the horizontal cross axis. The horizontal-versus-vertical labeling in the first option is the common mistake that only holds for row layouts.
Question 9 of 30
When you set position absolute on a child View in React Native, relative to what are its top and left offsets measured?
Show the answer
Answer: a · Its nearest positioned ancestor, typically the parent View
Absolute offsets are measured against the nearest positioned ancestor, usually the parent View, not the whole screen. React Native also has no position fixed, which is why screen-relative positioning is not the default behavior.
Question 10 of 30
To render a View as a perfect circle of width and height 80 with centered text, which combination is correct?
Show the answer
Answer: d · borderRadius 40 with justifyContent center and alignItems center on the parent
A circle needs borderRadius equal to half the equal width and height (40 for an 80 box), and centering on both axes requires both justifyContent and alignItems set to center. Using only one alignment leaves the text off-center on the other axis.
Question 11 of 30
Why does a nested Text inherit color and fontSize from its parent while a nested View inherits nothing?
Show the answer
Answer: c · Text maps to platform attributed-text where spans inherit attributes, while Views are independent boxes with no general style cascade
Text inheritance reflects native attributed-text systems where text runs cascade attributes; Views are deliberately independent layout boxes with no cascade. React Native does not implement a general CSS cascade, so the first and last options are wrong.
Read the full bite: Why Text inherits styles but View does not
Question 12 of 30
Under the New Architecture, what is the most accurate primary reason StyleSheet.create outperforms inline literal styles in long lists?
Show the answer
Answer: c · It provides stable object references, avoiding per-render allocations and reducing diff and GC pressure
The durable benefit is referential stability that cuts allocations and garbage during frequent list re-renders. The bridge-ID serialization story is much diminished under Fabric and JSI, so attributing the gain primarily to it today overstates the mechanism.
Read the full bite: How StyleSheet.create reduces styling overhead
Question 13 of 30
A developer sets the value prop on a TextInput but forgets to handle onChangeText. What happens when the user types?
Show the answer
Answer: c · The field appears frozen because state never updates, so value keeps overriding each keystroke
With value bound to unchanging state and no onChangeText to update it, every keystroke is immediately overwritten by the stale state, so the input looks frozen. This is the classic controlled-input mistake, not a thrown error.
Read the full bite: Controlled TextInput with value and onChangeText
Question 14 of 30
Why is Pressable typically preferred over Button for a custom-styled production button with multiple interaction states?
Show the answer
Answer: a · Pressable exposes a pressed state and multiple callbacks, allowing arbitrary custom feedback that Button cannot provide
Pressable gives a pressed state plus onPressIn, onPressOut, and onLongPress, enabling fully custom feedback, whereas Button is minimally styleable. Button still handles onPress fine, and TouchableOpacity is not deprecated, just less flexible.
Question 15 of 30
Using a single state object for a form, what is the correct way to update just the email field on change?
Show the answer
Answer: a · Call setForm(prev => spreading prev and overriding email) to preserve other fields immutably
Spreading the previous state and overriding only email keeps the other fields intact while updating immutably. Mutating directly skips proper re-renders, and replacing state with just the email key discards name and password.
Read the full bite: Single useState object for multi-input forms
Question 16 of 30
What is the practical difference between onStartShouldSetResponder and onMoveShouldSetResponder?
Show the answer
Answer: d · Start claims the touch immediately on contact, while Move lets a view claim it only after the finger moves, distinguishing taps from drags
onStartShouldSetResponder negotiates ownership at touch down, while onMoveShouldSetResponder lets a view wait and claim the gesture once movement begins, which is how a drag is separated from a tap. They are not aliases and Move does not precede Start.
Question 17 of 30
Why is keyboardShouldPersistTaps set to handled often preferred for a form inside a ScrollView?
Show the answer
Answer: d · It keeps the keyboard up when a child handles the tap, so buttons respond on the first tap, but dismisses it on background taps
The handled value passes taps to children that handle them while still dismissing the keyboard on empty taps, fixing the two-tap button problem. keyboardDismissMode is a separate prop for dismissal during scrolling, not the same thing.
Question 18 of 30
Why can a Reanimated and Gesture Handler animation stay smooth even when the JavaScript thread is blocked?
Show the answer
Answer: d · Gesture tracking and worklet-driven animation run on the native UI thread via shared values, independent of the JS thread per frame
Worklets and shared values let per-frame gesture and animation work run on the UI thread, so a busy JS thread does not stall it. The Animated native driver is more limited and does not provide gesture-driven worklets, so equating them is incorrect.
Read the full bite: Gesture Handler and Reanimated on the UI thread
Question 19 of 30
You repeatedly open Profile screens for different users and want each to stack so back steps through them. Which API and why?
Show the answer
Answer: a · push, because it unconditionally adds a new instance even if the route already exists
push always stacks a new instance, which is what a drill-down chain needs. navigate reuses an existing instance of the route rather than always adding one, and replace removes the current screen from history rather than stacking.
Question 20 of 30
Why nest a Stack Navigator inside each tab of a Tab Navigator rather than using the Tab Navigator alone?
Show the answer
Answer: a · So each tab keeps its own independent push and pop history and preserves its position when you switch away and back
Nesting a Stack in each tab gives every section independent drill-down history that survives tab switches. Tabs alone handle lateral switching, not per-tab back stacks, and the goal is independent history, not a shared global stack.
Read the full bite: Stack Navigator vs Tab Navigator and nesting
Question 21 of 30
Why is conditionally rendering separate auth and app stacks preferred over calling navigation.navigate after login?
Show the answer
Answer: c · State drives which screens exist, so the old stack is unmounted and unreachable
Declarative conditional rendering ties screen existence to auth state, automatically unmounting unreachable stacks. The navigate approach leaves the login screen on the back stack, which is exactly the bug to avoid.
Read the full bite: Structuring an auth flow in React Navigation
Question 22 of 30
Why does a useEffect with an empty dependency array fail to refetch when the user returns to a stacked screen?
Show the answer
Answer: d · The screen remains mounted, so the effect runs only once on first mount
Pushing a screen does not unmount the one beneath it, so a mount-only effect never re-runs on return. useFocusEffect fires on each focus, which is what triggers the refetch.
Read the full bite: Refetching data when a screen gains focus
Question 23 of 30
Which approach correctly navigates from an Axios interceptor that runs outside any React component?
Show the answer
Answer: c · Use a navigationRef passed to NavigationContainer and call navigate after isReady
Hooks only work inside components, so useNavigation throws in an interceptor. A navigationRef gives non-React code a stable handle, guarded by isReady to avoid early calls.
Read the full bite: Accessing navigation outside a screen component
Question 24 of 30
You need a header title that updates live as the user edits a text field held in component state. What should you use?
Show the answer
Answer: b · navigation.setOptions inside useLayoutEffect with the state as a dependency
The static options object evaluates outside the component and cannot see evolving state. setOptions in useLayoutEffect updates the header from current state without a visible flash.
Read the full bite: Setting screen options statically versus dynamically
Question 25 of 30
A candidate adds a linking screens map for posts/:id but the link never opens the app. What is the most likely cause?
Show the answer
Answer: c · The native scheme or intent filter was not registered, so the OS never routes the URL
Without the iOS URL type or Android intent filter, the operating system never delivers the URL to your app, so the JS config never runs. The path syntax and param parsing are fine.
Read the full bite: Configuring deep linking to a parameterized screen
Question 26 of 30
What does react-native-screens primarily change about how a deep React Navigation stack behaves?
Show the answer
Answer: b · It detaches inactive screens from the native view hierarchy so their native views can be freed
The library backs screens with native containers and detaches inactive ones from the native tree, releasing their views. It does not necessarily unmount JS state, and it is unrelated to list virtualization.
Read the full bite: How react-native-screens optimizes a deep stack
Question 27 of 30
What makes navigation.navigate('Post', { id }) statically checked for correct route name and params?
Show the answer
Answer: c · A ParamList passed to the navigator and to the typed useNavigation generic
The ParamList maps names to param shapes; supplying it to the navigator and the useNavigation generic lets TypeScript autocomplete names and enforce params. Casting to any discards all of that.
Question 28 of 30
Why can rendering a thousand-item list inside a ScrollView cause performance problems that a FlatList avoids?
Show the answer
Answer: d · ScrollView mounts all children at once, while FlatList virtualizes to render only visible items
ScrollView eagerly mounts all children, spiking memory and startup time. FlatList renders only the viewport plus a buffer, keeping cost roughly constant regardless of list length.
Read the full bite: ScrollView versus FlatList for long lists
Question 29 of 30
Why is using the array index as keyExtractor problematic for a list where items can be deleted or reordered?
Show the answer
Answer: a · React matches elements by key, so shifting indices attach state and views to the wrong items
Keys identify items across renders. When indices shift after a delete or reorder, React reconciles by position and binds row state to the wrong item. A stable id avoids this.
Read the full bite: FlatList data, renderItem, and keyExtractor
Question 30 of 30
Blank cells appear during fast scrolling of fixed-height rows. Which single change most directly reduces the blanks?
Show the answer
Answer: c · Provide getItemLayout so FlatList positions cells without measuring them
getItemLayout lets FlatList compute positions instantly for known heights, cutting the lag that produces blanks. A huge windowSize trades blanks for memory pressure and new jank.
Read the full bite: Diagnosing slow FlatList scroll and blank cells
Could you explain these out loud?
That is what an interview actually tests. Tezvyn gives you questions like these with what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.