Skip to content
tezvyn:

Top 30 Intermediate React Native Interview Questions and Answers

30 intermediate multiple-choice React Native interview questions, past the definitions: how the pieces fit together, what breaks in practice, and the trade-off behind a choice. They come from 30 bites in the React Native library, the middle slice of the 140 React Native interview questions in the 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.

  1. Question 1 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

  2. Question 2 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

  3. Question 3 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.

    Read the full bite: alignItems vs justifyContent in flexbox

  4. Question 4 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.

    Read the full bite: Using position absolute in React Native

  5. Question 5 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.

    Read the full bite: Circular View with centered text

  6. Question 6 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

  7. Question 7 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.

    Read the full bite: Gesture Responder System lifecycle

  8. Question 8 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.

    Read the full bite: keyboardShouldPersistTaps in ScrollView

  9. Question 9 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

  10. Question 10 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

  11. Question 11 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

  12. Question 12 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

  13. Question 13 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

  14. Question 14 of 30

    A FlatList row should highlight when an external selectedId state changes, but nothing updates. What is the correct fix?

    Show the answer

    Answer: a · Pass selectedId to the extraData prop so FlatList re-evaluates its rows

    FlatList is a PureComponent that only reacts to changes in tracked props like data and extraData. Passing selectedId via extraData signals it to re-render; mutating data in place breaks reference equality.

    Read the full bite: Re-rendering FlatList on external state change

  15. Question 15 of 30

    Why does infinite scroll often load the same page multiple times, and how is it prevented?

    Show the answer

    Answer: c · onEndReached can fire repeatedly during a scroll; an in-flight loading guard prevents overlapping fetches

    onEndReached can fire several times near the end during a fling. Without a loading or hasMore guard, each fire starts a fetch, duplicating pages. The guard ensures one request at a time.

    Read the full bite: Implementing infinite scroll with FlatList

  16. Question 16 of 30

    For a chat list mixing 60px text and 220px image rows, what makes scrollToIndex land accurately and reduce blanks?

    Show the answer

    Answer: d · A getItemLayout that returns each row's true length and precomputed cumulative offset

    Accurate per-item length and offset let FlatList position rows without measuring and jump scrollToIndex to the exact pixel. A constant average height misaligns offsets after the first differing row.

    Read the full bite: Optimizing FlatList with variable item heights

  17. Question 17 of 30

    A component reading only user.name re-renders on every theme toggle from a combined context. What fixes it?

    Show the answer

    Answer: d · Split theme and user into separate contexts so the consumer subscribes only to what it uses

    A context value change re-renders all consumers regardless of fields used, so React.memo does not help. Splitting into separate contexts means the name consumer ignores theme changes entirely.

    Read the full bite: Context re-renders when unrelated value changes

  18. Question 18 of 30

    Which action inside a Redux reducer violates its core principles?

    Show the answer

    Answer: a · Calling an API and dispatching based on the response from within the reducer

    Reducers must be pure: no side effects and no mutation. Performing an API call inside one breaks purity; async work belongs in middleware like thunks. The other options are correct reducer behavior.

    Read the full bite: Redux principles: store, actions, reducers

  19. Question 19 of 30

    Why must asynchronous API calls live in middleware rather than directly inside a Redux reducer?

    Show the answer

    Answer: d · Reducers must remain pure and synchronous, returning new state without side effects

    Reducers must be pure and synchronous so state transitions stay predictable and replayable; side effects belong in middleware. Middleware does not run on a separate thread, making that distractor wrong.

    Read the full bite: Handling async API calls in Redux

  20. Question 20 of 30

    What architectural difference lets Zustand expose store state without wrapping the component tree in a Provider?

    Show the answer

    Answer: c · It stores state in a module-level closure that the generated hook reads from directly

    Zustand keeps state in a closure outside React and returns a hook that subscribes to it, so no Provider is required. It does not wrap Context or sit on top of Redux, making those options incorrect.

    Read the full bite: Redux versus Zustand state management

  21. Question 21 of 30

    Why should an automatic retry-with-backoff strategy generally exclude HTTP 4xx responses?

    Show the answer

    Answer: d · 4xx indicates a flawed request, so repeating it unchanged will keep failing

    A 4xx means the client request is invalid, so retrying it without change yields the same error; only transient 5xx or connectivity issues benefit from backoff. 4xx are application-layer responses, not network failures, so that option is wrong.

    Read the full bite: Robust network error handling strategy

  22. Question 22 of 30

    What bug occurs if a request interceptor injects a header but forgets to return the config object?

    Show the answer

    Answer: a · Axios sends the request with an undefined config, likely throwing or losing all options

    A request interceptor must return the config; omitting the return passes undefined down the chain, breaking the request. Axios does not skip the interceptor or auto-compensate, so the other options are incorrect.

    Read the full bite: Axios interceptors for auth headers

  23. Question 23 of 30

    Beyond saving bandwidth, what subtle bug does aborting a stale fetch on navigation prevent?

    Show the answer

    Answer: b · A slower earlier response overwriting newer data, a race condition

    Cancellation prevents an outdated in-flight response from resolving later and clobbering fresher state, a classic race condition. Aborting does not leak memory, trigger retries, or permanently block requests, so those are wrong.

    Read the full bite: Cancelling fetch with AbortController

  24. Question 24 of 30

    What problem common to REST does a GraphQL query directly solve when a screen needs only a few fields from related resources?

    Show the answer

    Answer: d · Over-fetching and multiple round trips, by returning exactly the requested fields in one request

    GraphQL lets the client request precisely the fields it needs in a single call, avoiding REST's over-fetching and extra round trips. GraphQL still needs auth, REST can be cached, and REST responses can be schema-validated, so those options are false.

    Read the full bite: GraphQL versus REST data fetching

  25. Question 25 of 30

    Which scenario most strongly favors platform-specific files over a Platform.OS check inside one component?

    Show the answer

    Answer: c · One platform imports a native module that does not exist on the other

    Separate files let the bundler exclude a native module from the platform that lacks it, avoiding import errors; inline Platform.OS cannot do that. The other cases are tiny tweaks best handled inline, so they do not justify file splitting.

    Read the full bite: Platform files versus Platform.OS checks

  26. Question 26 of 30

    What mistake can occur when comparing Platform.Version directly with a numeric operator on iOS?

    Show the answer

    Answer: b · iOS returns the version as a string, so a numeric comparison may behave unexpectedly without parsing

    On iOS Platform.Version is a string like '17.4', so you should parse it before numeric comparison, whereas Android returns a numeric API level. It is neither a Date, undefined, nor an Android API level, so those options are wrong.

    Read the full bite: Conditional logic with Platform.Version

  27. Question 27 of 30

    You want a card to fade in and scale up at the same time as a single visual entrance. Which composition helper fits, and why not the other?

    Show the answer

    Answer: b · Animated.parallel, because it starts both the opacity and scale animations simultaneously

    Parallel starts all child animations at once so fade and scale read as one entrance. Sequence would run them one after the other, and stagger intentionally offsets the start times.

    Read the full bite: Animated.sequence versus Animated.parallel

  28. Question 28 of 30

    Why can Reanimated keep a gesture-driven animation smooth even when the JavaScript thread is busy, while the legacy Animated API often cannot?

    Show the answer

    Answer: d · Reanimated runs the animation logic as worklets on the UI thread instead of round-tripping through the JS bridge

    Reanimated executes worklets and reads shared values on the UI thread, avoiding the asynchronous bridge for per-frame logic. The legacy API must cross the bridge for reactive or gesture-driven values, so a blocked JS thread stalls it.

    Read the full bite: Animated API versus Reanimated architecture

  29. Question 29 of 30

    In Reanimated, what is the correct way to animate a component when a shared value should move to a new target?

    Show the answer

    Answer: d · Assign sharedValue.value to withTiming or withSpring of the target inside an event handler

    You mutate the .value property, wrapping the target in an animation helper like withTiming so the UI thread interpolates smoothly. Reading .value into React state defeats the off-thread model and risks stale values.

    Read the full bite: Shared values and useAnimatedStyle in Reanimated

  30. Question 30 of 30

    Why is mapping scroll position to an Animated.Value via Animated.event with useNativeDriver preferable to reading contentOffset in a JS onScroll handler and calling setState?

    Show the answer

    Answer: c · Animated.event with the native driver updates the value on the native side each frame, avoiding per-frame bridge traffic and re-renders

    The native-driven mapping keeps the value updating natively without JS round trips or re-renders, so the parallax stays smooth. The setState approach fires React updates every frame and crosses the bridge, causing jank. The native driver still only supports transform and opacity.

    Read the full bite: Animated.event for scroll-driven parallax

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.

Get it on Google PlayiPhone app coming soon