React Application Development Interview Questions

50 questions and answers covering React Application Development, from fundamentals through practical, debugging, and design-level topics.

50 of 50 interview questions

  1. What does JSX actually compile to?beginnerComponents & JSX

    JSX compiles to plain JavaScript function calls -- `<div className="a">Hi</div>` becomes something like `React.createElement("div", { className: "a" }, "Hi")` (or a `jsx()` call with the modern transform). JSX is syntax sugar, not a separate templating language.

  2. What is the difference between a React element and a React component?intermediateComponents & JSX

    An element is a plain, immutable description of what to render (the object JSX compiles to); a component is a function (or class) that returns elements -- React calls your component functions to produce the elements it then renders.

  3. What are props, and can a component modify its own props?beginnerComponents & JSX

    Props are read-only inputs passed from a parent to a child component. A component must never mutate its own props -- one-way data flow means data flows down through props, and changes flow back up through callbacks the parent provides.

  4. Why does React require a unique `key` prop when rendering a list of elements?intermediateComponents & JSX

    Keys let React's reconciliation algorithm match elements across renders to determine which items were added, removed, or reordered, rather than re-rendering the entire list from scratch.

  5. Why is using an array index as a list `key` risky when the list can be reordered or filtered?advancedComponents & JSX

    If items are reordered, inserted, or removed, the index-to-item mapping shifts, so React can incorrectly reuse a DOM node (and its internal state) for a different logical item than before -- a stable, unique identifier from the data itself is safer.

    Common mistake: Using the array index as `key` for a reorderable or filterable list, causing component state to attach to the wrong item after a reorder.

  6. What is a fragment (`<>...</>`) and why is it useful?beginnerComponents & JSX

    A fragment lets a component return multiple sibling elements without wrapping them in an extra DOM node like a `<div>`, avoiding unnecessary markup in the rendered output.

  7. What is 'composition' in React, and why is it generally preferred over deep prop drilling?intermediateComponents & JSX

    Composition means building complex UI by nesting and combining smaller components (often via the `children` prop) rather than passing every piece of data or behavior down through many prop layers -- it keeps intermediate components decoupled from data they don't use directly.

  8. What is 'prop drilling,' and what are two ways to avoid it?intermediateComponents & JSX

    Passing a prop through several intermediate components that don't use it themselves, just to reach a deeply nested child. It can be avoided with composition (passing the component itself down as `children`/a prop) or with Context for genuinely widely-needed data.

  9. Why must a custom component's name start with a capital letter in JSX?intermediateComponents & JSX

    JSX uses capitalization to distinguish a custom component (`<MyButton />`, compiled as a component reference) from a built-in host element (`<button />`, compiled as a string tag name) -- a lowercase custom component name would be misinterpreted as an HTML tag.

  10. What does 'component thinking' mean when decomposing a UI mockup into React components?advancedComponents & JSX

    Breaking a UI into well-scoped pieces where each component has a single clear responsibility and owns only the state it genuinely needs -- rather than one giant component handling everything, or components split so finely that data has to be threaded awkwardly between them.

  11. What does calling a `useState` setter function actually do?beginnerState & Events

    It schedules a re-render with the new state value; it does not mutate the existing state variable synchronously in place, and the update may be batched together with other state updates before React actually re-renders.

  12. Why does using the functional update form (`setCount(c => c + 1)`) matter when updating state based on its previous value?advancedState & Events

    State updates can be batched, so `count` inside a closure might be stale by the time an update actually applies. The functional form receives the true latest value at update time, avoiding lost updates when multiple updates are scheduled close together.

    Common mistake: Calling setCount(count + 1) multiple times in the same handler expecting each call to add one, when they all read the same stale `count` closure value.

  13. Why shouldn't you directly mutate a state array (e.g. `state.push(item)`) instead of creating a new array?intermediateState & Events

    React compares state by reference to decide whether to re-render; mutating the existing array in place doesn't create a new reference, so React may not detect the change and skip re-rendering.

  14. What is the difference between a controlled and an uncontrolled form input?intermediateState & Events

    A controlled input's value is driven entirely by React state (`value={state}` + `onChange`); an uncontrolled input manages its own value internally in the DOM, read via a ref only when needed rather than tracked in state on every keystroke.

  15. What is a synthetic event in React?advancedState & Events

    A cross-browser wrapper object around the native DOM event that React passes to event handlers, normalizing behavior across browsers while still exposing the underlying native event when needed.

  16. When should state be lifted to a common parent component?intermediateState & Events

    When two or more sibling components need to share or stay synchronized on the same piece of state -- lifting it to their nearest common ancestor and passing it down (with a callback to update it) keeps a single source of truth instead of duplicated, potentially inconsistent local state.

  17. Why is deciding what actually needs to be React state (versus a plain derived value computed during render) an important design choice?advancedState & Events

    Storing a value in state that could instead be computed from existing state/props on every render risks the two falling out of sync and adds unnecessary re-render triggers -- deriving it during render keeps a single source of truth.

  18. What is the difference between rendering `list.length === 0 && <Empty />` and a full explicit conditional with `if`/`else`-style branches?advancedState & Events

    Both can render conditionally, but `&&` short-circuit rendering has a known pitfall: if the left side evaluates to `0` (a falsy but renderable number) rather than `false`, React renders the literal `0` on the page instead of nothing.

    Common mistake: Writing `{count && <Badge count={count} />}`, which renders a stray "0" on the page when count is 0.

  19. How do you pass data from a child component back up to its parent?beginnerState & Events

    The parent passes a callback function down as a prop; the child calls that function (often with an argument) when something happens, letting the parent update its own state in response -- data itself still only flows down through props.

  20. What are the four states a real, data-driven UI typically needs to handle explicitly?intermediateState & Events

    Loading, error, empty (successfully loaded but no data), and success/populated -- a component that only handles the success case will show a confusing blank or broken UI in the other three situations.

  21. What is `useEffect` used for?beginnerEffects & Data Fetching

    Synchronizing a component with something outside React's own rendering -- e.g. fetching data, subscribing to an external event source, or manually manipulating a DOM node not managed by React.

  22. What does the dependency array passed to `useEffect` control?intermediateEffects & Data Fetching

    It tells React when to re-run the effect: an empty array (`[]`) means run once after the first render only; omitting the array means run after every render; a list of values means re-run whenever any of those values changes between renders.

  23. What is a cleanup function in `useEffect`, and when does it run?advancedEffects & Data Fetching

    An optional function returned from the effect callback; React runs it before the effect re-runs on a later render, and once more when the component unmounts -- used to cancel subscriptions, timers, or in-flight requests started by the effect.

  24. What is a race condition in a data-fetching `useEffect`, and how is it typically avoided?advancedEffects & Data Fetching

    If the effect re-runs (e.g. an id prop changes) before a previous fetch finishes, the older, now-stale response could resolve after the newer one and incorrectly overwrite it. It's typically avoided with a cleanup flag or an `AbortController` that ignores/cancels the outdated request.

    useEffect(() => {
      let cancelled = false;
      fetchUser(id).then((data) => {
        if (!cancelled) setUser(data);
      });
      return () => {
        cancelled = true;
      };
    }, [id]);

    Common mistake: Fetching data on prop change without a cancellation guard, so a slow earlier request can overwrite a faster, more recent one.

  25. Why shouldn't `fetch()` calls generally go directly in the component body during render?advancedEffects & Data Fetching

    Rendering must stay a pure, predictable calculation of UI from state/props -- triggering a network request as a side effect of render can fire duplicate requests on every re-render and makes the component's behavior unpredictable; side effects belong in `useEffect` (or an event handler) instead.

  26. What is a common mistake with an object or array literal in a `useEffect` dependency array?advancedEffects & Data Fetching

    A new object/array literal (e.g. `{ id }`) is a different reference on every render, even with identical contents -- putting it directly in the dependency array causes the effect to re-run on every render, defeating the purpose of the dependency array.

    Common mistake: Passing a freshly-created object or array literal as a dependency, causing the effect to re-run on every render regardless of the actual data.

  27. What is a custom hook, and what naming convention must it follow?intermediateEffects & Data Fetching

    A reusable function that itself calls other hooks (`useState`, `useEffect`, etc.) to encapsulate reusable stateful logic across components -- its name must start with `use` so React's linter and runtime rules-of-hooks checks can recognize it as a hook.

  28. What are the 'Rules of Hooks,' and why must hooks always be called in the same order?advancedEffects & Data Fetching

    Hooks must only be called at the top level of a component or custom hook (never inside loops, conditions, or nested functions), because React tracks each hook's state by the order it was called in during render -- conditionally skipping a hook call shifts that order and corrupts state tracking for subsequent hooks.

  29. What is the difference between `useEffect` and `useLayoutEffect`?advancedEffects & Data Fetching

    `useEffect` runs asynchronously after the browser has painted the screen; `useLayoutEffect` runs synchronously after DOM mutations but before the browser paints, useful when you need to measure or adjust the DOM before the user sees a visual flicker.

  30. Why is it usually better to fetch data based on a prop/state dependency inside `useEffect` rather than fetching once in a parent and passing everything down?intermediateEffects & Data Fetching

    It keeps a component self-sufficient and re-usable, and lets it automatically refetch when the relevant dependency (like an id) changes, without requiring the parent to know about or coordinate every child's data needs.

  31. What is React Context used for, and when should it be avoided?intermediateContext, Performance & Testing

    Context lets you share a value across a component tree without manually threading it through every intermediate component's props -- appropriate for genuinely global-ish data (theme, current user, locale). It should be avoided for state that only a couple of nearby components need, where prop passing or composition is simpler and keeps components more independently testable.

  32. What is a common performance pitfall with Context, particularly with frequently-changing values?advancedContext, Performance & Testing

    Every component consuming a Context re-renders whenever the Context's value changes, even if that component only cares about part of the value -- putting fast-changing data in a broad Context can cause much more re-rendering than passing that specific data as a targeted prop.

  33. What does `React.memo` do, and when is it actually worth applying?advancedContext, Performance & Testing

    It skips a component's re-render if its props are shallowly equal to the previous render's props. It's worth applying to components that render often with unchanged props and are expensive to re-render -- applying it everywhere by default adds comparison overhead without necessarily helping.

  34. What is the difference between `useMemo` and `useCallback`?advancedContext, Performance & Testing

    `useMemo` memoizes a computed value between renders (recomputing only when its dependencies change); `useCallback` memoizes a function reference itself (returning the same function identity across renders unless dependencies change) -- `useCallback(fn, deps)` is roughly equivalent to `useMemo(() => fn, deps)`.

  35. What is an error boundary, and what kinds of errors does it NOT catch?advancedContext, Performance & Testing

    A component (implemented with a class component's `componentDidCatch`/`getDerivedStateFromError`, or a library helper) that catches rendering errors in its child tree and shows a fallback UI instead of crashing the whole app. It does not catch errors in event handlers, async code, or errors thrown during server rendering outside its own render.

  36. Why do accessible components need visible focus states and correct semantic HTML elements, rather than relying purely on visual styling and `<div>`s with click handlers?intermediateContext, Performance & Testing

    Keyboard and screen-reader users rely on semantic elements (`<button>`, `<label>`, headings in order) and visible focus indicators to navigate and understand the page -- a clickable `<div>` with no semantic role or focus handling is invisible to assistive technology and unusable via keyboard alone.

    Common mistake: Building an interactive control as a styled <div onClick> instead of a real <button>, making it unreachable and unusable by keyboard and screen-reader users.

  37. What is the philosophy behind testing components by 'what the user sees and does' (e.g. with React Testing Library) rather than testing internal component implementation details?advancedContext, Performance & Testing

    Tests that query the rendered DOM by visible text/roles and simulate real user interactions stay valid even if a component's internal implementation (state shape, hooks used) is refactored -- tests that reach into internal state or instance methods break on refactors that don't actually change user-facing behavior.

  38. What is the virtual DOM, and how does it relate to reconciliation?intermediateContext, Performance & Testing

    The virtual DOM is React's lightweight in-memory representation of the UI tree; reconciliation is the process of comparing (diffing) the new virtual DOM tree against the previous one to compute the minimal set of real DOM updates needed, rather than re-rendering the entire page.

  39. Why might over-fetching data in a top-level parent and passing it down through many layers of unrelated components be a maintainability problem, even if it 'works'?advancedContext, Performance & Testing

    It couples unrelated components to data-fetching concerns they don't otherwise need, makes each intermediate component harder to reuse or test in isolation, and often means a small UI change requires threading new props through several layers that shouldn't need to know about it.

  40. When deciding where state should live in a component tree, what question should you ask first?advancedContext, Performance & Testing

    Which component(s) actually need this state to render correctly, and is it the single source of truth or does it duplicate/derive from state that already exists elsewhere -- state should generally live in the lowest common ancestor of every component that reads or writes it, and nowhere higher than necessary.

  41. What is the `children` prop, and how does it enable a reusable layout/wrapper component?beginnerArchitecture & Patterns

    `children` is the special prop containing whatever JSX is nested between a component's opening and closing tags -- a component like `<Card>{...}</Card>` can render a consistent wrapper around arbitrary content without knowing what that content is in advance.

  42. What is a higher-order component (HOC), and why have custom hooks largely replaced this pattern?advancedArchitecture & Patterns

    An HOC is a function that takes a component and returns a new, enhanced component (e.g. `withAuth(Component)`). Custom hooks generally achieve the same reuse of stateful logic with less indirection (no wrapper component, no prop-name collisions), which is why hooks are now the more common pattern.

  43. What is `React.lazy` used for?advancedArchitecture & Patterns

    It lets you code-split a component into a separate bundle chunk, loaded only when that component is actually rendered -- typically paired with `<Suspense>` to show a fallback while the chunk downloads, reducing the app's initial bundle size.

  44. What is a React portal, and what is a typical use case?advancedArchitecture & Patterns

    `createPortal` renders a component's output into a DOM node outside its normal parent hierarchy in the tree, while it still behaves as a child in React's component tree (for context, event bubbling) -- commonly used for modals/tooltips that need to escape a parent's `overflow: hidden` or `z-index` stacking context.

  45. How does client-side routing (e.g. with a router library) avoid a full page reload when navigating between views?intermediateArchitecture & Patterns

    The router intercepts navigation, updates the browser's URL via the History API, and swaps which components are rendered based on the current path -- all without the browser issuing a new full-page request to the server.

  46. Why might a large single component that both fetches data and renders complex UI be harder to test and maintain than splitting it into a data-fetching hook plus a presentational component?advancedArchitecture & Patterns

    Splitting separates two different concerns (data-fetching logic and rendering logic) that change for different reasons -- the presentational half can be tested and reused with mock data alone, without needing to mock network calls just to verify rendering.

  47. What is the difference between client-side rendering (CSR) and server-side rendering (SSR) in a React app?advancedArchitecture & Patterns

    CSR ships a mostly-empty HTML shell and renders everything in the browser via JavaScript after it loads; SSR renders the initial HTML on the server per request, so the browser receives already-populated markup, generally improving perceived load time and SEO before client-side JavaScript takes over ('hydrates') the page.

  48. What does 'hydration' mean in the context of server-rendered React?advancedArchitecture & Patterns

    The process where React attaches event listeners and internal state to the already-rendered server HTML in the browser, making the static markup interactive, without re-rendering the DOM from scratch if the server and client output match.

  49. Why is putting a `key` prop only on the outermost element of a mapped list (not on inner elements) the correct approach?advancedArchitecture & Patterns

    React only reads `key` on the direct children of the element performing the mapping/reconciliation for that list -- putting it deeper inside each list item's own children has no effect on how React tracks and diffs the list items themselves.

  50. Why is designing a component's prop interface (what it accepts, and what it deliberately doesn't) an architectural decision, not just a typing exercise?advancedArchitecture & Patterns

    A narrow, well-considered prop interface keeps a component's responsibilities clear and prevents callers from coupling to internal implementation details it wasn't designed to expose -- an overly permissive interface (e.g. accepting a raw style object or an arbitrary render callback for everything) tends to make future refactors riskier.