Fossils⚛ïļ React PatternsReact Core Fundamentals Interview Questions
ðŸĢHatchlingReactReconciliationKeysControlled Components

React Core Fundamentals Interview Questions

Reconciliation, keys, controlled components — the fundamental questions every React interview starts with.

React Core Fundamentals Interview Questions

These three questions come up in almost every React interview. They seem basic — but your depth of understanding here sets the tone for the entire conversation.


Q1: What Is Reconciliation in React?

Interview Question: "How does React decide what to update in the actual DOM?"

The Simple Explanation

Think of it like editing a Google Doc. You don't delete the whole document and retype it every time you fix a typo — you just change the specific words that need fixing. React does the same thing with your webpage.

When your data changes, React doesn't throw away the entire page and rebuild it. Instead, it:

  1. Creates a new "blueprint" of what the UI should look like (the Virtual DOM)
  2. Compares the new blueprint to the old one (this comparison is called diffing)
  3. Updates only the parts that actually changed in the real DOM

This whole process is called reconciliation.

How the Diff Algorithm Works

React's diffing algorithm is smart but makes two big shortcuts to stay fast:

  • Different element types = full replacement. If a <div> becomes a <span>, React doesn't try to morph one into the other. It tears down the entire subtree and builds a new one.
  • Keys tell React which items are which. In a list, React uses key to match items between the old and new render. Without keys, it matches by position (index), which causes bugs.
function TodoList({ todos }) {
  return (
    <ul>
      {todos.map(todo => (
        // React uses this key to track each todo across renders
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
}

What About Fiber?

React's reconciliation engine is called Fiber (introduced in React 16). Think of it like upgrading from a single-lane road to a multi-lane highway.

The old reconciler processed the entire component tree in one go — if you had 10,000 components, the browser froze until it was done. Fiber breaks the work into small units called "fibers" and can:

  • Pause in the middle of rendering
  • Prioritize urgent updates (like typing) over slow ones (like filtering a huge list)
  • Resume or abandon work that's no longer needed

The One-Liner That Impresses

"Reconciliation is React's O(n) diffing algorithm that compares virtual DOM trees using element type and key identity, powered by Fiber — a linked-list architecture that makes rendering interruptible so the browser never freezes."

Common Follow-Up Questions

"What's the difference between the render phase and the commit phase?"

The render phase is where React calls your component functions and figures out what changed — no DOM mutations happen here, and React can restart this work. The commit phase is where React applies all the changes to the real DOM in one synchronous pass.

"Why do component functions need to be pure?"

Because Fiber can call your component function multiple times during the render phase (it might pause and restart). If your component has side effects like API calls directly in the render body, those would fire multiple times unpredictably.

Red Flags in Your Answer

  • Saying "React re-renders the whole page" — it doesn't, that's the whole point
  • Describing the Virtual DOM without explaining how the diff actually works
  • Not mentioning Fiber or the two-phase (render/commit) process
  • Thinking reconciliation only happens on mount — it happens on every update

Q2: What Are Keys and Why Are They Important?

Interview Question: "What is the key prop in React and why does it matter?"

The Simple Explanation

Think of it like a classroom attendance sheet. If you just go by seat number (position), and a new student sits in the front row, suddenly every student after them is "wrong" — student 2 is now in seat 3, student 3 is in seat 4, etc. The teacher has to update every record.

But if each student has a unique student ID, the teacher just adds the new student and everyone else stays the same. That's what key does for React.

Keys give each item in a list a stable identity so React can track which items were added, removed, or moved — instead of re-rendering the entire list.

The Index-as-Key Trap

This is the #1 mistake beginners make:

// BAD — using index as key
{todos.map((todo, index) => (
  <TodoItem key={index} todo={todo} />
))}
 
// GOOD — using a stable, unique identifier
{todos.map(todo => (
  <TodoItem key={todo.id} todo={todo} />
))}

Why is index-as-key dangerous? Watch what happens when you add an item to the beginning of a list:

Before:                    After adding "Buy milk":
index 0 → "Walk dog"      index 0 → "Buy milk"   ← React thinks this is "Walk dog" updated
index 1 → "Do laundry"    index 1 → "Walk dog"    ← React thinks this is "Do laundry" updated
                           index 2 → "Do laundry"  ← React thinks this is NEW

React matches by key. With index keys, every item looks "changed" because they all shifted positions. With todo.id keys, React would correctly see that only "Buy milk" is new.

This causes real bugs: form inputs show the wrong values, animations target the wrong elements, and component state gets mixed up between items.

When Is Index-as-Key Actually OK?

Only when ALL three conditions are true:

  1. The list is static (items never reorder, add, or delete)
  2. Items have no state (no inputs, no toggles)
  3. Items have no stable IDs available

If any of those conditions is false — use a real unique ID.

The Key Reset Trick

You can use key to force a component to remount from scratch:

// When userId changes, the entire Profile component
// unmounts and remounts with fresh state
<Profile key={userId} userId={userId} />

This is useful when you want to reset all internal state (form fields, scroll position, etc.) when the "identity" of the data changes.

The One-Liner That Impresses

"Keys are reconciliation hints — they tell React which items have a stable identity across renders, so it can reuse fibers instead of destroying and recreating DOM nodes. Using index as key silently breaks list reordering, input state, and animations."

Common Follow-Up Questions

"What happens if two siblings have the same key?"

React will warn in development and may produce unpredictable behavior — it can't tell the items apart, so it might reuse the wrong component instance and mix up their state.

"Can you use keys outside of lists?"

Yes! Putting a key on any component tells React to treat it as a new instance when the key changes. It's a pattern for resetting component state without writing manual reset logic.

Red Flags in Your Answer

  • Saying keys are "just to suppress the console warning"
  • Always using index as key without explaining the tradeoffs
  • Not being able to explain what goes wrong when keys are wrong (state mixups, wrong DOM updates)
  • Not knowing the key-reset pattern for remounting components

Q3: What Are Controlled vs Uncontrolled Components?

Interview Question: "What's the difference between controlled and uncontrolled components in React?"

The Simple Explanation

Think of it like driving a car.

A controlled component is like having your hands on the steering wheel at all times. You decide every turn. React state is the steering wheel — you control the input's value, and every change goes through your code.

An uncontrolled component is like putting the car on cruise control and letting the road decide. The DOM keeps track of the value internally. You just read it when you need it (usually on form submit).

Controlled Component

React state is the "single source of truth." Every keystroke updates state, and the input reads from state.

function ControlledForm() {
  const [email, setEmail] = useState('');
 
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setEmail(e.target.value);
  };
 
  return (
    <form onSubmit={() => console.log(email)}>
      <input
        type="email"
        value={email}
        onChange={handleChange}
      />
    </form>
  );
}

Why use this? You get full control — validation on every keystroke, formatting as the user types (like adding dashes to a phone number), disabling the submit button until the form is valid.

Uncontrolled Component

The DOM holds the value. You use a ref to read it when needed.

function UncontrolledForm() {
  const emailRef = useRef<HTMLInputElement>(null);
 
  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    console.log(emailRef.current?.value);
  };
 
  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        ref={emailRef}
        defaultValue=""
      />
    </form>
  );
}

Why use this? Simpler for basic forms, integrates easily with non-React code (like a jQuery date picker), and avoids a re-render on every keystroke.

The Decision Framework

ScenarioUse ControlledUse Uncontrolled
Real-time validationYesNo
Conditional disable/submitYesNo
Format input as user typesYesNo
Simple form, submit onceOverkillYes
Integrating non-React librariesHardYes
File inputs (<input type="file">)Not possibleAlways

The Gotcha: Mixing Controlled and Uncontrolled

// BUG: starts uncontrolled (no value), then becomes controlled
const [name, setName] = useState(undefined);
<input value={name} onChange={e => setName(e.target.value)} />
 
// FIX: always provide a defined initial value
const [name, setName] = useState('');
<input value={name} onChange={e => setName(e.target.value)} />

React will warn if a component switches from uncontrolled to controlled (or vice versa) during its lifetime. Always initialize string state with '', not undefined.

The One-Liner That Impresses

"In a controlled component, React state is the single source of truth for the input value — every change flows through state. In an uncontrolled component, the DOM owns the value and you read it imperatively via refs. Most production forms use controlled components for validation and UX, with refs reserved for file inputs and third-party integrations."

Common Follow-Up Questions

"Which should you use for a large form with many fields?"

Controlled — but with a form library like React Hook Form. It uses refs internally for performance but gives you a controlled API with validation, error handling, and minimal re-renders.

"What about <input type="file">?"

File inputs are always uncontrolled in React. You can't programmatically set a file input's value (browser security restriction), so you must use a ref to read the selected file.

Red Flags in Your Answer

  • Not knowing the difference between value and defaultValue
  • Saying "always use controlled" without acknowledging the performance tradeoff
  • Not mentioning the undefined-to-defined gotcha
  • Forgetting that file inputs are always uncontrolled
  • Unable to explain when you'd choose one over the other