Explain what React fragments change in the real DOM (no extra wrapper node) and what they still represent in React’s tree (a Fragment fiber). Connect this to reconciliation: identity/type matching, keys (especially keyed fragments in lists), and common remount/state-loss gotchas when adding/removing a fragment wrapper.
How do fragments affect the rendered DOM and reconciliation?
Use guided tracks for structured prep, then practice company-specific question sets when you want targeted interview coverage.
Core idea
A fragment (<>...</> / React.Fragment) is invisible in the browser DOM (no extra element node), but it is still a node in React’s internal tree. That means it affects reconciliation (how React matches old vs new children), even though it doesn’t produce a DOM wrapper.
Topic | What happens | Why it matters |
|---|---|---|
Rendered DOM | Fragment adds no extra DOM element; only its children are inserted | No accidental wrappers that break CSS layout, semantics ( |
React tree | React still creates a Fragment “fiber” that groups children | Reconciliation can treat “Fragment vs not Fragment” as a type change (can remount) |
Props/attributes | Fragments don’t create a DOM node, so you can’t attach DOM attributes/events/layout hooks to “the fragment itself” | If you need a className, ref to a DOM element, or an event boundary, you need a real element wrapper |
How reconciliation sees fragments
Reconciliation matches elements by type + key + position. A fragment has a distinct element type (Fragment). So introducing/removing a fragment wrapper can change the element type at that position, and React may tear down and recreate that subtree.
Scenario | What React compares | Typical result |
|---|---|---|
Same fragment, children change | Fragment type stays; React diffs children inside it | Child components can preserve state if their own identity is stable |
Fragment ↔ element wrapper swap ( | Type changes at that position | Subtree often remounts (state reset) because old fiber is replaced |
Fragment present ↔ fragment removed (wrapping/unwrapping) | Type at the position changes (Fragment vs Child) | Can remount the child even if it “looks like the same UI” |
Fragments in lists with keys | Keyed Fragment gives identity to a group of siblings | Prevents incorrect reuse when returning multiple siblings per list item |
// ✅ DOM stays clean (no wrapper)
function Header() {
return (
<>
<h1>Title</h1>
<p>Subtitle</p>
</>
);
}
// DOM output is roughly:
// <h1>Title</h1>
// <p>Subtitle</p>
// ✅ Keyed Fragment in a list (group multiple siblings per item)
function DefinitionList({ items }) {
return (
<dl>
{items.map((x) => (
<React.Fragment key={x.id}>
<dt>{x.term}</dt>
<dd>{x.desc}</dd>
</React.Fragment>
))}
</dl>
);
}
// Without a keyed Fragment, you'd need a wrapper element (often invalid inside <dl>).
// ⚠️ Gotcha: wrapping/unwrapping can remount (state loss)
function Counter() {
const [n, setN] = React.useState(0);
return <button onClick={() => setN((x) => x + 1)}>{n}</button>;
}
function App({ wrap }) {
// If `wrap` toggles, React may replace the subtree because
// the element type at this position changes (Fragment vs Counter).
return wrap ? (
<>
<Counter />
</>
) : (
<Counter />
);
}
Gotcha | What you see | Fix / rule of thumb |
|---|---|---|
Using fragment when you needed a layout hook | You can’t style/measure “the fragment” (no DOM node) | Use a real element when you need className/ref/layout boundary |
Swapping wrappers (Fragment vs | Unexpected remount / lost local state / lost focus | Keep wrapper type stable; don’t toggle between structurally different roots |
Returning multiple siblings per list item without a keyed Fragment | React warns about keys or reuses siblings incorrectly on reorder | Put the |
Interview framing
“Fragments don’t create DOM nodes, so they keep markup/semantics clean. But they still exist in React’s tree, so they participate in reconciliation: type + key + position. Keyed fragments are mainly for lists where one item returns multiple siblings. Be careful: adding/removing/swapping the fragment wrapper can change element identity and cause remounts.”
Fragments affect the DOM by removing unnecessary wrapper elements. They affect reconciliation because Fragment is still an element type in React’s tree: it can change identity matching (and therefore state preservation), and keyed fragments give stable identity to grouped siblings in lists.