HomeBytesheetsRoadmapsUI TemplatesUI ToolsStack Discussion
50 Topics
Chapter•300 Minutes

Part 2 - Complete React.js Progressive Master Question Bank

50 progressive React.js interview questions covering JSX compilation, Virtual DOM & Fiber architecture, Hooks internals, state management, SSR/RSC, and performance profiling.

Q1: What is the Virtual DOM and how does Reconciliation work in React?

The Virtual DOM (VDOM) is an in-memory lightweight JS object representation of the real DOM. When state or props change, React creates a new Virtual DOM tree and runs a diffing algorithm during Reconciliation to calculate the minimal set of real DOM operations required.

React Virtual DOM Reconciliation Lifecycle
Virtual DOM Representation Example
// What JSX converts into (Virtual DOM Node object)
const vdomNode = {
  type: 'button',
  props: {
    className: 'btn-primary',
    onClick: () => console.log('Clicked'),
    children: 'Submit'
  }
};
💡 JSX elements compile to plain JS objects describing element node type, properties, event listeners, and children.
Key Takeaways
  • Virtual DOM minimizes direct real DOM manipulations to boost rendering performance.
  • React uses a heuristics O(n) diffing algorithm during Reconciliation to compute minimal real DOM updates.
Knowledge Check

What is the primary benefit of React's Virtual DOM Reconciliation process?

Q2: What is React Fiber and how does it improve application responsiveness?

React Fiber is the re-implementation of React's core reconciliation algorithm introduced in React 16. It breaks rendering work into incremental units of work called Fiber nodes, enabling React to pause, resume, assign priority to, or abandon work as higher-priority user inputs arrive.

Fiber Priority Work Scheduler
Priority Work Interruption Model
// Fiber tree structure snippet (Internal React Node Representation)
const fiberNode = {
  type: 'div',
  child: childFiberNode,
  sibling: siblingFiberNode,
  return: parentFiberNode,
  pendingProps: nextProps,
  lanes: PriorityLanes // Tracks execution priority
};
💡 Fiber nodes use child, sibling, and return pointers to traverse trees iteratively without locking the JS call stack.
Key Takeaways
  • Replaces synchronous stack reconciliation with asynchronous cooperative scheduling.
  • Enables time-slicing and priority-based scheduling for smooth 60fps user interactions.
Knowledge Check

Which phase of Fiber execution is interruptible by higher-priority tasks?

Q3: How is JSX compiled under the hood in modern React?

JSX is a syntax extension for JavaScript. It does not run natively in browsers. Compilers like Babel transform JSX tags into React.createElement() calls (or _jsxRuntime.jsx() in React 17+ JSX transform) that return plain Virtual DOM objects.

JSX to JS Compilation Comparison
// 1. Input JSX
const element = <h1 className="title">Hello World</h1>;

// 2. Output (Compiled JS via Babel React 17+ Runtime)
import { jsx as _jsx } from 'react/jsx-runtime';
const element = _jsx('h1', { className: 'title', children: 'Hello World' });
💡 Compilers translate declarative JSX syntax into functional call trees creating React element descriptors.
Key Takeaways
  • JSX is syntactic sugar for React.createElement() or _jsx() calls.
  • Modern JSX transform eliminates the need to explicitly import React in every file.
Knowledge Check

What does a JSX tag <MyComponent /> evaluate to after compilation?

Q4: What is the fundamental difference between State and Props?

Props (short for properties) are read-only input parameters passed down from a parent component to a child component. State is internal data managed locally within a component that can change over time in response to user actions or network events, triggering re-renders.

Props vs State Usage
function CounterContainer() {
  const [count, setCount] = useState(0); // Local State
  return <CounterDisplay value={count} onIncrement={() => setCount(count + 1)} />; // Passed as Props
}

function CounterDisplay({ value, onIncrement }) {
  return <button onClick={onIncrement}>Count: {value}</button>;
}
💡 CounterContainer owns the count state and passes it down alongside updater callbacks as props to CounterDisplay.
Key Takeaways
  • Props flow unidirectionally downward and are immutable by the child component.
  • State is local, mutable via state updater functions, and triggers re-renders on update.
Knowledge Check

What happens if a child component attempts to reassign props.title = 'New Title' directly?

Q5: Why are 'keys' required when rendering lists in React, and why avoid index keys?

Keys give items in a list a stable identity. React uses keys during the reconciliation diffing process to identify which items were added, updated, or removed. Using array indices as keys can lead to subtle rendering bugs, input state corruption, and sub-optimal reconciliation if list items are reordered or filtered.

Unique ID Key Mapping
function TodoList({ todos }) {
  return (
    <ul>
      {todos.map(todo => (
        // RECOMMENDED: Unique item ID key
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
}
💡 Using a unique todo.id ensures React preserves component state correctly when list items move.
Key Takeaways
  • Keys allow React to match Virtual DOM list nodes across re-renders efficiently.
  • Avoid array indices as keys when items can be reordered, inserted, or removed.
Knowledge Check

What issue occurs when using array indices as keys for a dynamic reorderable list?

Q6: How does useState work internally and why is state batching used?

useState stores state variables inside the component Fiber node's linked list of hooks. Calling a state setter function enqueues a update action on the Fiber queue. React batches multiple state updates within event handlers into a single re-render cycle to optimize performance.

Functional State Updates & Automatic Batching
function Counter() {
  const [count, setCount] = useState(0);

  const handleMultipleIncrements = () => {
    // Functional updates queue operations on Fiber state queue
    setCount(prev => prev + 1);
    setCount(prev => prev + 1);
    // React batches these calls into a single component re-render pass
  };
  return <button onClick={handleMultipleIncrements}>Count: {count}</button>;
}
💡 Functional state updates evaluate sequentially against the queued Fiber state, updating count safely to 2.
Key Takeaways
  • Hook states are preserved inside a linked list attached to the component Fiber instance.
  • Automatic batching (React 18) combines multiple state updates into single re-render updates.
Knowledge Check

Why should you pass a callback function to setState (setCount(prev => prev + 1)) when new state depends on previous state?

Q7: How does useEffect manage side-effects, dependencies, and cleanup cycles?

useEffect executes side-effects after the component renders and DOM updates are committed. The dependency array controls when the effect executes: omitting it runs after every render, an empty array [] runs once on mount, and passing dependencies [a, b] runs when specified variables change. Returning a function triggers cleanup before re-executing or unmounting.

useEffect Execution & Cleanup Lifecycle
useEffect Subscription & Cleanup Pattern
useEffect(() => {
  const subscription = api.subscribeToData(id);
  
  // Cleanup closure function
  return () => {
    subscription.unsubscribe();
  };
}, [id]); // Re-subscribes if 'id' changes
💡 The returned unsubscribe function runs before re-subscribing on id change or when the component unmounts.
Key Takeaways
  • Runs asynchronously after paint to prevent blocking browser rendering.
  • Cleanup function executes prior to effect re-execution and component unmounting.
Knowledge Check

When does the cleanup function returned inside useEffect execute?

Q8: What are the Rules of Hooks and why are they enforced?

  1. Only call Hooks at the Top Level: Don't call Hooks inside loops, conditions, or nested functions.
  2. Only call Hooks from React Functions: Call Hooks from Functional Components or Custom Hooks. Enforced because React relies on the exact execution order of Hooks across re-renders to map state variables to internal Fiber linked list nodes.
Rules of Hooks Violation vs Correct Pattern
// ❌ BAD: Conditional Hook call alters Hook execution order
if (isLoggedIn) {
  useEffect(() => fetchUserData(), []);
}

// ✅ GOOD: Keep Hook top-level, move condition inside Hook
useEffect(() => {
  if (isLoggedIn) {
    fetchUserData();
  }
}, [isLoggedIn]);
💡 Keeping useEffect at the top level guarantees that Hook index pointers match internal Fiber node linked lists.
Key Takeaways
  • React tracks Hook states using an ordered linked list on the Fiber node.
  • Conditional Hook calls alter execution order, mismatching state bindings.
Knowledge Check

Why does calling a Hook inside an IF statement break React applications?

Q9: What is the difference between useMemo and useCallback?

  • useMemo: Caches the result value of an expensive calculation (useMemo(() => computeValue(a), [a])).
  • useCallback: Caches the function instance itself between re-renders (useCallback(() => handleClick(), [])) to prevent breaking child component React.memo reference equality checks.
useMemo vs useCallback Usage
// Memoize calculated result value
const expensiveValue = useMemo(() => {
  return calculateBigData(data);
}, [data]);

// Memoize callback function reference pointer
const handleAction = useCallback(() => {
  console.log('Action performed for id:', id);
}, [id]);
💡 useMemo skips re-calculating big data when data is unchanged; useCallback maintains identical handleAction references.
Key Takeaways
  • useMemo memoizes computed return values.
  • useCallback memoizes function reference pointers across renders.
Knowledge Check

What primary performance issue does useCallback solve when passing functions to memoized child components?

Q10: What is useRef and how does it differ from useState?

useRef returns a mutable object { current: initialValue } whose reference persists across re-renders. Modifying ref.current does not trigger a component re-render. It is used to access direct DOM nodes or store instance variables that shouldn't cause UI updates when mutated.

DOM Focus Control with useRef
function TextInputWithFocus() {
  const inputEl = useRef(null);
  
  const onButtonClick = () => {
    // Imperative focus targeting
    inputEl.current.focus();
  };
  
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus Input</button>
    </>
  );
}
💡 inputEl.current references the underlying native HTMLInputElement node directly.
Key Takeaways
  • Mutating .current updates values synchronously without causing a re-render.
  • Commonly used for imperative DOM access (focus, canvas, media playback) and timer IDs.
Knowledge Check

What happens to the UI component when you assign timerRef.current = setTimeout(...) inside a click handler?