Skip to content

Quiz: Reconciliation — What Updates?

advanced12 min read

Test Your Reconciliation Knowledge

You've been through fiber architecture, the diffing algorithm, keys, and the render/commit phases. Time to put it all together and see if you really get it. For each scenario, predict exactly what React does to the DOM.

Fair warning: these target the most common misunderstandings about reconciliation. If you get them all right on the first try, you understand React's internals better than most senior engineers.


Scenario 1: Type Change at Root

function App({ isAdmin }) {
  if (isAdmin) {
    return (
      <section>
        <Counter />
        <UserInfo />
      </section>
    );
  }
  return (
    <div>
      <Counter />
      <UserInfo />
    </div>
  );
}
// Counter has internal state: count = 5
// isAdmin changes from true to false
Quiz
What happens to Counter's state (count = 5) when isAdmin changes?

Scenario 2: Same Type, Different Props

function App({ theme }) {
  return (
    <div className={`app ${theme}`}>
      <h1 style={{ color: theme === 'dark' ? 'white' : 'black' }}>
        Welcome
      </h1>
      <Counter />
    </div>
  );
}
// theme changes from 'light' to 'dark'
Quiz
Which DOM operations does React perform?

Scenario 3: Conditional Rendering and Position

function App({ showBanner }) {
  return (
    <div>
      {showBanner && <Banner />}
      <Counter />
      <Footer />
    </div>
  );
}
// Counter has count = 10. showBanner changes from false to true.
Quiz
Does Counter keep its state (count = 10) when showBanner changes from false to true?

Scenario 4: List Reordering Without Keys

function App() {
  const [reversed, setReversed] = useState(false);
  const items = reversed
    ? ['Charlie', 'Bob', 'Alice']
    : ['Alice', 'Bob', 'Charlie'];

  return (
    <ul>
      {items.map(name => (
        <li>{name} <input defaultValue="" /></li>
      ))}
    </ul>
  );
}
// User types "hello" in Alice's input. Then clicks reverse.
Quiz
After reversing, which input contains 'hello'?

Scenario 5: Key-Based Reordering

function App() {
  const [reversed, setReversed] = useState(false);
  const items = reversed
    ? [{ id: 3, name: 'Charlie' }, { id: 2, name: 'Bob' }, { id: 1, name: 'Alice' }]
    : [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }];

  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>{item.name} <input defaultValue="" /></li>
      ))}
    </ul>
  );
}
// User types "hello" in Alice's input (id=1). Then clicks reverse.
Quiz
After reversing, which input contains 'hello'?

Scenario 6: Component Identity Change

function App({ mode }) {
  const Editor = mode === 'code' ? CodeEditor : TextEditor;
  return (
    <div>
      <Editor content="Hello world" />
    </div>
  );
}
// CodeEditor and TextEditor are different components.
// User is editing in CodeEditor. mode changes to 'text'.
Quiz
What happens to the editor's internal state (cursor position, undo history)?

Scenario 7: Fragment Children

function App({ count }) {
  return (
    <div>
      {count > 0 ? (
        <>
          <Badge count={count} />
          <Counter />
        </>
      ) : (
        <Counter />
      )}
    </div>
  );
}
// Counter has count = 7. count prop changes from 3 to 0.
Quiz
Does Counter preserve its state (count = 7) when the parent count changes from 3 to 0?

Scenario 8: Key Reset Pattern

function App() {
  const [selectedUserId, setSelectedUserId] = useState(1);

  return (
    <div>
      <UserSelector onSelect={setSelectedUserId} />
      <UserProfile key={selectedUserId} userId={selectedUserId} />
    </div>
  );
}

function UserProfile({ userId }) {
  const [editing, setEditing] = useState(false);
  const [draft, setDraft] = useState('');

  return (
    <div>
      <h1>User {userId}</h1>
      {editing ? (
        <textarea value={draft} onChange={e => setDraft(e.target.value)} />
      ) : (
        <button onClick={() => setEditing(true)}>Edit</button>
      )}
    </div>
  );
}
// User is editing User 1 with draft = "Hello". Selects User 2.
Quiz
What happens to UserProfile when switching from User 1 to User 2?

Key Takeaways

Key Rules
  1. 1Wrapper type changes (div → section) destroy the ENTIRE subtree — all child state is lost.
  2. 2Same type at same position = state preserved. Parent re-renders still trigger child re-renders, but state survives.
  3. 3Without keys, list items match by position. DOM state (input values, scroll position) stays at the position, not with the data.
  4. 4With keys, list items match by identity. DOM nodes move with their keys, preserving both React state and DOM state.
  5. 5Component type comparison is by reference (===). Different functions = different types = full remount.
  6. 6Fragments affect tree structure. Adding/removing elements around a component changes its position, potentially resetting state.
  7. 7Key changes on non-list elements force a clean remount — the 'key as reset' pattern for resetting component state.
  8. 8React.memo prevents re-rendering when props haven't changed, but it doesn't affect reconciliation or state preservation.