Skip to content
tezvyn:

Top 30 React & Next.js Interview Questions and Answers

30 multiple-choice questions on React & Next.js, of the kind that come up in a technical interview, drawn from 30 bites in the React & Next.js 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, Next.js, Remix, RSC, React ecosystem

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 can a standard browser not execute a .jsx file directly without a build step?

    Show the answer

    Answer: c · JSX must first be transpiled into React.createElement or jsx function calls

    JSX is syntax the JS engine does not understand, so a transpiler converts it to function calls first. Browsers never receive JSX; the CDN or MIME claims are irrelevant to the transpilation requirement.

    Read the full bite: What is JSX and how does the browser run it?

  2. Question 2 of 30

    A child component needs to change a value it received from its parent. What is the correct React pattern?

    Show the answer

    Answer: c · Call a callback function passed down from the parent via props

    Props are immutable and flow one-way from parent to child, so the child must invoke a callback prop to request that the parent update the data. Mutating a prop directly breaks React's rendering assumptions and will not trigger a re-render.

    Read the full bite: Explain props in React and how parent components pass data to children

  3. Question 3 of 30

    Which accurately describes the two primary ways to define a React component?

    Show the answer

    Answer: c · Function components and class components, with function components being the standard for new React 19 code

    Function components and class components are the two distinct definition paradigms, and function components are the React 19 default. Arrow functions and function declarations are merely alternate syntaxes for the same function component paradigm, not separate ways to define components.

    Read the full bite: What are the two main ways to define a component in React?

  4. Question 4 of 30

    When a dynamic list reorders and items have local state, what happens if array indices are used as React keys?

    Show the answer

    Answer: d · React reuses component instances by position, causing state from one data item to appear on another.

    Array indices tie identity to position, so React reuses the wrong component instance after reorder or deletion and state ends up attached to the wrong data item. Option B is wrong because React does not reset state when keys are unstable—it incorrectly preserves it on the reused instance.

    Read the full bite: What is the purpose of React's key prop and index key risks?

  5. Question 5 of 30

    In React, when is an early return with if/else preferable to an inline ternary inside JSX?

    Show the answer

    Answer: a · When branches are large, structurally different, or to reduce nesting

    Early returns improve readability when branches are large, structurally different, or deeply nested. Option B actually describes when an inline ternary is the better choice, not an early return.

    Read the full bite: Describe two patterns for conditional rendering in JSX

  6. Question 6 of 30

    Why would wrapping two table cells in a Fragment be preferable to wrapping them in a div?

    Show the answer

    Answer: a · Fragments avoid creating an invalid HTML structure since they do not add an extra DOM node.

    A div placed directly inside a table row creates invalid HTML, while a Fragment groups children without introducing any DOM node. Claiming a performance benefit is a common misconception; the primary reason to use Fragments is structural and semantic correctness, not optimization.

    Read the full bite: What is a React Fragment and why use it over a div?

  7. Question 7 of 30

    A team passes a user object through Layout, Header, Navigation, and finally to UserMenu. What is the strongest argument for replacing this with Context or composition?

    Show the answer

    Answer: a · Layout, Header, and Navigation are coupled to a prop they ignore, making refactors and reuse harder.

    Prop drilling is primarily a maintenance and coupling problem: intermediaries must accept and forward props they do not use, so renaming the prop or reusing those components elsewhere becomes painful. Option B is tempting but wrong because the card explicitly warns against confusing drilling with runtime performance issues like excessive re-renders.

    Read the full bite: Explain prop drilling and why it's a problem

  8. Question 8 of 30

    Which call reflects how Babel transforms the JSX <a href='/home' className='link'>Go Home</a> into React.createElement()?

    Show the answer

    Answer: b · React.createElement('a', {href: '/home', className: 'link'}, 'Go Home')

    The JSX transform emits a quoted string for lowercase host tags, places attributes in the second argument preserving className, and passes text children as the third argument, not inside props. Option A is tempting because the resulting element object has props.children, but the createElement API signature requires children as a separate argument from props.

    Read the full bite: Write the React.createElement() equivalent for this JSX

  9. Question 9 of 30

    Why can using array indices as keys cause state pollution when a list is reordered?

    Show the answer

    Answer: d · React relies on keys to identify elements across renders; indices make React match DOM nodes to the wrong data, preserving state for the wrong item.

    Keys provide sibling-scoped identity, not just a performance shortcut; when indices are reused after reordering, React incorrectly associates the old DOM node and its state with new data. Option A is wrong because keys fundamentally determine state preservation, so unstable keys create correctness bugs rather than merely slower reconciliation.

    Read the full bite: How does React use keys in reconciliation? When do keys cause bugs?

  10. Question 10 of 30

    What is the key architectural difference between passing a render function prop and passing a component reference prop in React?

    Show the answer

    Answer: a · A render function is called by the child with internal data, letting the parent control what renders while the child controls when and where.

    This captures inversion of control: the parent supplies the function (what to render) and the child invokes it with internal data (when and where). Option D is tempting because both patterns enable reuse, but HOCs wrap components at definition time while render props compose at runtime.

    Read the full bite: Can you pass a React component as a prop? Explain Render Props.

  11. Question 11 of 30

    Which pattern correctly wires a text input as a controlled component using useState?

    Show the answer

    Answer: a · Initialize useState with an empty string at the top level, bind the input value to the state variable, and update it via onChange by calling the setter with event.target.value.

    The correct pattern requires calling useState at the top level with an empty string, binding the input value to state, and updating via the setter in onChange. Option C is tempting because it mentions binding value, but calling useState conditionally violates the Rules of Hooks and direct mutation prevents React from re-rendering.

    Read the full bite: How do you use useState to track user input?

  12. Question 12 of 30

    What happens to a useEffect's cleanup and setup when a value in its dependency array changes?

    Show the answer

    Answer: a · React runs the previous cleanup with old values first, then runs setup with the new values

    React always runs the previous effect's cleanup with the old dependency values before running the new setup when a dependency changes. The most tempting distractor is wrong because cleanup is not reserved for unmount; it runs whenever dependencies change to prevent stale subscriptions or leaks.

    Read the full bite: Explain useEffect dependency array behavior for [], [deps], and omitted

  13. Question 13 of 30

    You need to increment a React state variable three times within a single event handler. Which approach produces the correct final value?

    Show the answer

    Answer: c · Call setCount(prev => prev + 1) three times sequentially

    Option C uses the functional updater so React queues each increment against the latest pending state. Option B fails because all three calls read the same closed-over value from the render snapshot, so each computes 0 + 1.

    Read the full bite: What will count be after three setCount calls in a row?

  14. Question 14 of 30

    Which approach correctly fetches data inside useEffect while preventing memory leaks when the component unmounts?

    Show the answer

    Answer: a · Create an async function inside the effect, invoke it, and return a cleanup function that aborts the request.

    Creating an async function inside the effect allows the outer callback to remain synchronous and return an abort cleanup function. Declaring the useEffect callback itself as async is a common mistake because it returns a Promise, breaking React's cleanup contract.

    Read the full bite: How do you fetch data with useEffect and prevent memory leaks?

  15. Question 15 of 30

    A useEffect subscribes to an external store. When a dependency changes and the effect must re-run, when does the cleanup function execute?

    Show the answer

    Answer: d · Immediately before the effect re-runs with the new dependency values

    React runs the cleanup function immediately before re-executing an effect when dependencies change, tearing down the previous render's side effects to prevent memory leaks and stale subscriptions. The most tempting distractor assumes cleanup is only for unmount, but that ignores the re-run scenario and fails under React 18 Strict Mode, which intentionally double-invokes effects to expose missing teardown logic.

    Read the full bite: What is the purpose of the useEffect cleanup function?

  16. Question 16 of 30

    What is the key difference between useState(expensive()) and useState(() => expensive()) during re-renders?

    Show the answer

    Answer: a · The direct call executes on every render but React discards its result after mount, while the function runs only once during initialization.

    JavaScript evaluates the direct argument before React can intercept it, so expensive() wastes cycles on every render even though React throws away the result after mount; the initializer function runs only once. Option D is tempting but wrong because lazy initialization does not prevent re-renders, it only avoids repeating expensive setup work inside them.

    Read the full bite: Why pass a function to useState for expensive initial values?

  17. Question 17 of 30

    You must measure a rendered DOM element and immediately adjust a modal to prevent visual flicker. Which choice is correct?

    Show the answer

    Answer: d · useLayoutEffect, because it runs synchronously after DOM mutations but before paint, letting you correct layout before it is visible

    useLayoutEffect runs synchronously after React commits DOM changes but before the browser paints, so layout corrections happen before the user sees anything. Option C is tempting because it names the right hook but incorrectly claims it runs after paint, which would actually cause the flicker you are trying to prevent.

    Read the full bite: When would you choose useLayoutEffect over useEffect?

  18. Question 18 of 30

    How should you refactor an effect that needs the latest prop value inside a polling interval without listing that prop as a dependency?

    Show the answer

    Answer: b · Lift the prop value into a ref and read the ref inside the interval with an empty dependency array.

    Lifting the prop into a ref lets the interval read the latest value without re-subscribing, because refs are mutable and do not trigger re-renders. Disabling the rule and reading the prop directly hides the stale closure from the linter and leaves the code vulnerable to refactor hazards.

    Read the full bite: Why is exhaustive-deps critical and when can you disable it?

  19. Question 19 of 30

    In which scenario is replacing prop drilling with React Context most justified?

    Show the answer

    Answer: c · When data must travel through several components that do not use it themselves to reach a deep descendant

    Prop drilling is threading props through intermediate components that do not need the data to reach a deep descendant, which is the specific architectural pain that justifies Context. Eliminating all prop passing is wrong because doing so adds indirection, obscures data flow, and can trigger broad re-renders when shallow prop passing is still perfectly fine.

    Read the full bite: What is prop drilling in React?

  20. Question 20 of 30

    When designing a reusable Card component that should wrap arbitrary content like headings, paragraphs, or buttons, why is using children preferable to using a dedicated body prop?

    Show the answer

    Answer: a · Because the Card can remain a presentational wrapper that does not need to know what markup it contains

    Using children lets the Card stay a layout wrapper while the parent decides the content, avoiding tight coupling. The tempting idea that body props only accept strings is wrong—custom props can technically receive JSX, but using them for composition forces the wrapper to know about specific content structures.

    Read the full bite: How does children work, and why is it fundamental to composition?

  21. Question 21 of 30

    Why must a custom hook's name start with use?

    Show the answer

    Answer: d · So React's linter can enforce the Rules of Hooks

    The use prefix signals to ESLint that the function contains hook calls, enabling the Rules of Hooks linter to verify unconditional calls and correct dependencies. Option B is a common misconception: custom hooks reuse stateful logic, but each call maintains independent state unless combined with Context.

    Read the full bite: What is a custom hook? Write a simple useToggle example.

  22. Question 22 of 30

    For which situation should you reach for useReducer instead of multiple useState hooks?

    Show the answer

    Answer: d · Coordinating several related fields that must update atomically from one action

    useReducer excels when one action must update multiple interdependent fields atomically, centralizing transition logic outside the component. Option A is a common misconception because the hook itself does not memoize child renders or improve performance without additional optimizations like React.memo.

    Read the full bite: Explain useReducer and when to prefer it over useState

  23. Question 23 of 30

    A ThemeContext.Provider wraps the entire app and passes an unmemoized object containing theme and toggleTheme. What is the main performance risk?

    Show the answer

    Answer: d · Every consumer re-renders whenever the Provider re-renders because the object reference changes each time

    React compares context values by reference, so a new object literal on every render triggers re-renders in all consumers even if the theme data is unchanged. Option A is tempting because developers often assume context supports selective subscriptions by property, but React does not optimize that way.

    Read the full bite: Use useContext to provide theme state without prop drilling

  24. Question 24 of 30

    A parent computes an expensive object and defines an inline handler passed to a React.memo child. Which hook combination correctly optimizes the computation and prevents unnecessary child re-renders?

    Show the answer

    Answer: d · useMemo for the object and useCallback for the handler

    useMemo caches the computed object value, while useCallback preserves the function reference so React.memo's Object.is check sees an unchanged prop and skips the child render. Choosing useMemo for the handler confuses the two hooks because useMemo caches the returned value rather than the function reference, and omitting a hook creates a new inline function on every parent render.

    Read the full bite: Explain the difference between useMemo and useCallback

  25. Question 25 of 30

    What fundamental difference distinguishes a custom hook from a HOC when reusing stateful logic in React?

    Show the answer

    Answer: b · A custom hook extracts logic into a plain function without adding nodes to the component tree.

    Custom hooks reuse stateful logic as plain functions without adding nodes to the React tree or hiding prop sources, whereas HOCs wrap components and can create wrapper hell. Option D is tempting because it echoes the common misconception that hooks are just syntactic sugar for HOCs, but they represent a fundamentally different composition mechanism.

    Read the full bite: Compare HOCs and custom hooks for sharing logic

  26. Question 26 of 30

    In a context-reducer feature, a component only dispatches actions but never reads state. How do you prevent it from re-rendering when state changes?

    Show the answer

    Answer: c · Provide state and dispatch through two separate contexts and consume only the dispatch context

    Splitting state and dispatch into two contexts lets components subscribe only to the stable dispatch function, isolating them from state reference changes. React.memo cannot prevent re-renders caused by a changing context value, and useReducer already returns a stable dispatch, so memoizing it with useCallback does not solve the subscription problem.

    Read the full bite: Describe combining useContext and useReducer for scalable feature state

  27. Question 27 of 30

    When a React Server Component fetches data required by deeply nested Client Components, which pattern correctly respects the server-client boundary?

    Show the answer

    Answer: b · Pass the fetched data as serializable props to the Client Components or to a Client wrapper that distributes them

    Server Components must communicate with Client Components through serializable props because props are the only channel across the RSC boundary. Creating Context in a Server Component is incorrect because Context cannot be created in a Server Component and consumed by a Client Component.

    Read the full bite: Pass server-fetched data from Server Components to nested Client Components

  28. Question 28 of 30

    In a useEffect with setInterval reading a state variable, which fix removes the stale closure without leaking or duplicating timers?

    Show the answer

    Answer: b · Add the state variable to the dependency array and return a cleanup that clears the interval

    Adding the state to the dependency array and returning a cleanup that clears the interval recreates the callback with the latest value and prevents leaks. The functional updater distractor is wrong because functional updates only help inside setState, not inside intervals or event listeners where the closure remains stale.

    Read the full bite: What is a stale closure in React hooks?

  29. Question 29 of 30

    Why can two separate React components both use the class .button without style collisions when using CSS Modules?

    Show the answer

    Answer: c · The build tool hashes each class into a unique string scoped to its module

    CSS Modules rely on the build tool to automatically rewrite local class names into unique hashes like Button_button__3x7a9, so identical names in different files never collide. Option D is tempting because it sounds like React is managing the styles, but the scoping is purely build-time and involves no runtime JavaScript logic.

    Read the full bite: How do CSS Modules solve global scope conflicts in React?

  30. Question 30 of 30

    In a Next.js App Router project, where should you import a global CSS file so it applies to every route without causing build errors?

    Show the answer

    Answer: c · At the top of the root app/layout.js file

    Next.js restricts global CSS imports to root-level files in the App Router, so the root layout.js is the correct singleton entry point. Importing inside page.js or components is explicitly blocked to prevent cascade duplication, and a custom Document component is the Pages Router convention, not the App Router idiomatic solution.

    Read the full bite: Where and how to import global stylesheets in Next.js

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