Skip to the solution
EasyFrontend5 min read

What are fragments in React?

485 views

The problem

Question presented to candidate: "A component needs to return two sibling elements. What are your options, and why would you reach for a Fragment?"

What a strong answer should cover:

  • A component returns one value, so multiple siblings need a single parent β€” a Fragment is that parent without the DOM cost.
  • A Fragment renders no DOM node at all; children land directly in the parent element.
  • Two syntaxes: the shorthand <>...</> and the explicit <Fragment>...</Fragment>.
  • The shorthand cannot take a key. Mapping over a list that emits sibling pairs requires the long form.
  • Why the wrapper div actually matters: it breaks CSS layout contracts (flex/grid parent-child relationships), produces invalid HTML inside <table>, <dl>, <ul>, and adds depth to the DOM.
  • Fragment is exported from both react and react/jsx-runtime β€” the same symbol.
  • Nuance: Fragments accept only key and children; no className, no style, no ref.

Clarifying questions expected:

  • "Is this inside a list where each item emits multiple siblings?" β€” that decides shorthand versus long form.

Code / implementation expected: Yes β€” a keyed Fragment inside a map is the case worth showing.

  • fragments
  • dom
  • jsx
  • rendering

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

5 min read Β· 9 sections

Try it in the playground

Open any example in the playground to run and change it.

ReactKeyed Fragments in a definition list, and what a wrapper div breaks
import { Fragment, useState } from "react";

const ROWS = [
  { id: 1, term: "Fragment", def: "Groups children with no DOM node" },
  { id: 2, term: "Element", def: "The frozen object a component returns" },
];

export default function App() {
  const [wrap, setWrap] = useState(false);

  return (
    <div style={{ padding: 24, fontFamily: "system-ui", lineHeight: 1.6 }}>
      <h3>A definition list has no legal wrapper element</h3>
      {/* Each row emits a <dt> AND a <dd>. A <div> here would be invalid HTML,
          so a keyed Fragment is the only correct option. The shorthand <></>
          cannot take a key, hence the explicit form. */}
      <dl style={{ border: "1px solid #ddd", borderRadius: 8, padding: 12 }}>
        {ROWS.map((r) => (
          <Fragment key={r.id}>
            <dt style={{ fontWeight: 600 }}>{r.term}</dt>
            <dd style={{ margin: "0 0 8px 16px", color: "#555" }}>{r.def}</dd>
          </Fragment>
        ))}
      </dl>

      <h3>Flex styles direct children only</h3>
      <label style={{ display: "block", marginBottom: 8 }}>
        <input type="checkbox" checked={wrap} onChange={(e) => setWrap(e.target.checked)} />{" "}
        wrap the items in a div instead of a Fragment
      </label>

      <div style={{ display: "flex", gap: 8, border: "2px dashed #4f46e5", padding: 8 }}>
        {wrap ? (
          // The div becomes the single flex item; the boxes inside it stack.
          <div>
            <Box label="one" />
            <Box label="two" />
            <Box label="three" />
          </div>
        ) : (
          // Each box is a direct child, so each is its own flex item.
          <>
            <Box label="one" />
            <Box label="two" />
            <Box label="three" />
          </>
        )}
      </div>
      <p style={{ color: "#666", fontSize: 13 }}>
        Tick the box: with a div in the way the three boxes stop being flex
        items and stack vertically, because flex applies to direct children.
      </p>
    </div>
  );
}

function Box({ label }) {
  return (
    <span style={{ background: "#eef", border: "1px solid #99f", borderRadius: 6, padding: "6px 12px" }}>
      {label}
    </span>
  );
}

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 16 of 119 in React.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All React.js questions
Up nextEasy

What is the Virtual DOM in React?

Continue