Skip to content
tezvyn:

Top 30 Easy React & Next.js Interview Questions and Answers for Freshers

30 easy multiple-choice React & Next.js interview questions, the ones an interviewer opens with: definitions, everyday syntax, and the quick checks that you have really used it. They come from 30 bites in the React & Next.js library, the gentlest slice of the 144 React & Next.js 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, 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

    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?

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

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

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

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

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

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

  11. Question 11 of 30

    When a user clicks an internal link, what fundamentally distinguishes client-side routing from server-side routing?

    Show the answer

    Answer: a · Client-side routing intercepts navigation, swaps views with JavaScript, and updates the URL without fetching a new HTML document from the server.

    The correct answer captures the core architectural difference: the browser owns navigation by intercepting clicks and updating views via JavaScript without requesting a new HTML document. The virtual DOM distractor is tempting but wrong because it confuses routing with rendering, when the real distinction is who controls the document lifecycle.

    Read the full bite: What is the fundamental difference between client-side and server-side routing?

  12. Question 12 of 30

    In React Router v6, when two Route paths could both match the current URL, which component picks exactly one to render?

    Show the answer

    Answer: a · Routes, because it ranks all child matches and renders only the best fit

    Routes is the matching engine that ranks its child Route elements and renders exactly the best fit. Switch is the old v5 component; it does not replace Routes in v6, which uses ranked matching rather than simply stopping at the first match.

    Read the full bite: Primary roles of BrowserRouter, Routes, and Route, and basic route setup

  13. Question 13 of 30

    In a React single-page application, what is the key technical difference between using a framework Link component and a standard anchor tag for internal navigation?

    Show the answer

    Answer: b · Link intercepts the click event and updates the URL using the History API without requesting a new document from the server

    Link intercepts the click and uses the History API to change the URL without unloading the page, preserving in-memory React state and avoiding CSS/JS reparsing. The distractor that claims Link is merely a stylistic wrapper is wrong because it fundamentally alters the browser navigation lifecycle to enable client-side routing.

    Read the full bite: Why use Link over <a> for internal navigation?

  14. Question 14 of 30

    Which statement correctly describes a trade-off of uncontrolled React inputs?

    Show the answer

    Answer: b · They avoid re-renders but hide the value from React until explicitly read

    Uncontrolled inputs store value in the DOM, so React cannot react to changes until the value is explicitly read from a ref, which sacrifices live validation for less boilerplate. Distractor B is tempting because refs are indeed used with uncontrolled inputs, but live validation is impossible because React has no visibility into the keystrokes.

    Read the full bite: Explain controlled vs uncontrolled React form inputs and trade-offs

  15. Question 15 of 30

    Which set of practices best represents the idiomatic React approach when building a basic controlled form that submits without reloading the page?

    Show the answer

    Answer: c · Attach onSubmit to the form, call preventDefault, bind each input to useState, and read the values from state in the handler.

    Option C is correct because it combines semantic onSubmit for accessibility, preventDefault to stop page reload, and controlled state as the single source of truth. Option A is tempting because useRef offers direct DOM access, but that signals an imperative jQuery-like mindset that bypasses React's rendering cycle.

    Read the full bite: How do you handle a basic form submission in React?

  16. Question 16 of 30

    Which approach correctly prevents a child component from re-rendering when its props are unchanged?

    Show the answer

    Answer: a · Wrap the child component with React.memo to let React reuse its previous output when props match

    React.memo is a higher-order component that compares previous and next props with Object.is and reuses the last rendered output, skipping the component call entirely. The most tempting distractor suggests using useMemo to block rendering, but useMemo is a hook that only caches a computed value inside a component and does not prevent that component from executing.

    Read the full bite: Explain the difference between React.memo and useMemo

  17. Question 17 of 30

    Why does a React.memo child re-render when its parent passes an inline arrow function with identical code?

    Show the answer

    Answer: d · Because the function is recreated as a new object on each parent render, failing the shallow prop comparison

    The correct answer is C because inline functions are recreated as new object references on every parent render, causing React.memo's shallow comparison to see a changed prop. Distractor A is tempting because beginners often assume React performs deep equality checks, but React.memo only does shallow comparison by default.

    Read the full bite: Child re-renders with unchanged props: function identity and useCallback fix

  18. Question 18 of 30

    You wrap a component in React Profiler and inspect an update render. If actualDuration is almost the same as baseDuration, what should you conclude?

    Show the answer

    Answer: c · Most descendants likely re-rendered unnecessarily, suggesting missing memoization

    actualDuration close to baseDuration during an update means the subtree rendered nearly as slowly as the worst-case scenario, indicating missing memoization. Option A reverses this logic: actualDuration much lower than baseDuration signals that memoization is working.

    Read the full bite: How would you use React Profiler to find unnecessary re-renders?

  19. Question 19 of 30

    Which scenario most clearly justifies choosing Redux or Zustand over React Context and useState?

    Show the answer

    Answer: b · Twenty distant widgets must independently react to a high-frequency shared data feed.

    A global store shines when many distant components need rapidly changing state, because Context would force every consumer to re-render on each update. Using Redux for server-state caching is a common misconception; tools like React Query are purpose-built for that.

    Read the full bite: When would you choose Redux or Zustand over React's built-in hooks?

  20. Question 20 of 30

    In Redux, what correctly occurs after a reducer returns new state but before the UI re-renders?

    Show the answer

    Answer: a · The store replaces its state and notifies subscribed listeners

    The store replaces its state and notifies subscribed listeners so the UI can read the updated state; D is tempting because beginners often assume the reducer return immediately causes re-render, but Redux requires the subscription notification step.

    Read the full bite: How do Redux actions, reducers, and click-to-render data flow work?

  21. Question 21 of 30

    You need to query a styled submit button in a React test. Which query best aligns with React Testing Library's core philosophy?

    Show the answer

    Answer: a · screen.getByRole('button', { name: /submit/i }) because users look for a button labeled Submit

    React Testing Library prioritizes queries that mirror real user behavior, so getByRole matches how users actually perceive buttons. Choosing getByTestId is a common anti-pattern because it relies on invisible implementation details rather than user-facing semantics, sacrificing user fidelity for perceived stability.

    Read the full bite: How does React Testing Library's guiding principle influence query choice?

  22. Question 22 of 30

    Which testing strategy should you prefer when verifying that a React title component renders its prop correctly?

    Show the answer

    Answer: a · Query the rendered h1 by heading role and assert it is in the document

    Querying by heading role validates what a user and assistive technologies actually experience, which is the core philosophy of React Testing Library, whereas Enzyme shallow rendering tests implementation details instead of real DOM behavior.

    Read the full bite: How would you unit test a React title component?

  23. Question 23 of 30

    What is the key difference between using userEvent.type and fireEvent.change to test typing into a text input?

    Show the answer

    Answer: c · userEvent.type simulates the full browser event sequence and checks element interactability

    userEvent.type dispatches the complete sequence of events a real browser would fire and validates that the element is visible and enabled, whereas fireEvent.change only triggers a single event without guardrails. Option A is tempting but backwards: bypassing guardrails allows tests to pass when the UI is actually broken for real users.

    Read the full bite: What are fireEvent and user-event, and why prefer user-event?

  24. Question 24 of 30

    To create a publicly accessible /dashboard route in the Next.js App Router, which setup is required?

    Show the answer

    Answer: a · A file named app/dashboard/page.js that exports a React component by default

    The App Router requires a page.js file with a default export inside the route segment to create an addressable page; layout.js only wraps children and does not create a route, while app/dashboard.js follows the Pages Router convention and will not work.

    Read the full bite: How do you create a /dashboard route in Next.js App Router?

  25. Question 25 of 30

    In Next.js App Router, how does a sidebar in layout.js behave during sibling navigation compared to one imported in every page.js?

    Show the answer

    Answer: a · The layout.js sidebar stays mounted and keeps its state, but the shared header remounts and loses state.

    layout.js remains mounted during sibling navigation, preserving local and DOM state, while a header imported into each page.js is destroyed and recreated on every route change. Option B is a common misconception because layout.js is a framework-level primitive with state guarantees, not merely a DRY pattern.

    Read the full bite: What is layout.js and how does it differ from shared headers?

  26. Question 26 of 30

    You are building a Next.js App Router page that fetches product data from a database and includes an interactive 'Add to Cart' button. What is the recommended approach?

    Show the answer

    Answer: a · Keep the page as a Server Component and import only the button as a Client Component

    The App Router defaults to Server Components for direct data access and minimal bundle size, while Client Components should be used granularly only where interactivity is needed. Option C is a common mistake that ships unnecessary JavaScript to the browser, and D incorrectly assumes Server Components can handle client-side interactions.

    Read the full bite: Key difference between Server and Client Components in Next.js?

  27. Question 27 of 30

    How do you correctly fetch data for static generation in a Next.js App Router Server Component?

    Show the answer

    Answer: a · Export an async component that calls native fetch directly in its body, producing prerendered static HTML.

    In the App Router, an async Server Component uses the built-in fetch API directly to fetch at build time for static routes. A incorrectly applies the Pages Router getStaticProps pattern, C wrongly uses client hooks that are forbidden in Server Components, and D is incorrect because fetch requires no import and the component must be async to use await.

    Read the full bite: How do you fetch data for SSG in a Next.js Server Component?

  28. Question 28 of 30

    You need a server-only JSON endpoint at /api/items in a Next.js App Router project. Which approach follows the correct convention?

    Show the answer

    Answer: c · Create app/api/items/route.js and export an async GET function that returns NextResponse.json()

    App Router Route Handlers require route.js with a named GET export returning NextResponse, and page.js cannot exist in the same segment. Option D is tempting because it uses the correct file name but wrongly applies the old Pages Router default handler pattern with raw Node res objects.

    Read the full bite: Create a basic GET API endpoint in Next.js App Router

  29. Question 29 of 30

    When handling a POST request in a Next.js App Router Route Handler, which approach correctly extracts the JSON body?

    Show the answer

    Answer: d · Export an async POST function that calls await request.json() and returns a standard Response object.

    Next.js App Router Route Handlers are built on standard Web APIs, so you await request.json() and return a Response object. The Express-style approach is wrong because req.body and res.json() do not exist in this environment.

    Read the full bite: How do you parse JSON body in a POST Route Handler?

  30. Question 30 of 30

    What does NextResponse.json() handle automatically that standard Web Response leaves to you?

    Show the answer

    Answer: a · Calling JSON.stringify and setting the Content-Type header

    NextResponse.json() auto-serializes the payload with JSON.stringify and sets the Content-Type header for you, while standard Response requires both steps manually. Distractor D is wrong because both approaches return a valid Response that Route Handlers accept, so the helper is not required for compatibility.

    Read the full bite: What is NextResponse.json() and how does it differ from standard Response?

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