React Fragment: 불필요한 래퍼 없이 요소를 묶는 방법

한눈에 보기

React Fragment는 여러 자식 요소를 추가 DOM 노드 없이 하나로 묶어 반환하게 해 주는 문법 요소다. 하나의 루트 요소 제약을 래퍼 없이 해결해 DOM 깊이와 CSS 레이아웃 문제를 예방하는 원리와 key 사용법을 정리한다.

최종 업데이트 2026.09.17

React Fragment(리액트 프래그먼트)는 여러 자식 요소를 추가 DOM 노드 없이 하나로 묶어 반환하게 해 주는 React의 문법 요소다. JSX에서 컴포넌트는 반드시 하나의 루트 요소만 반환해야 하는데, Fragment를 사용하면 의미 없는 래퍼(wrapper) 요소를 만들지 않고도 이 제약을 지킬 수 있다. 그 결과 DOM 트리가 불필요하게 깊어지는 것을 막고 CSS 레이아웃이 깨지는 문제도 예방할 수 있다.

하나의 루트 요소 제약과 Fragment의 등장

JSX는 브라우저가 그대로 이해하는 문법이 아니라 컴파일 단계에서 함수 호출로 변환되는 표현식이다. 자바스크립트 함수가 값 하나를 반환하듯이 컴포넌트도 표현식 하나, 곧 루트 요소 하나를 반환해야 한다. 형제 요소 여러 개를 그대로 나란히 반환하려고 하면 문법 오류가 발생한다.

Fragment가 없던 시절에는 이 제약을 피하려고 습관적으로 div로 감싸는 코드가 많았다. 그러나 이런 래퍼는 화면 구조상 아무 의미가 없는데도 실제 DOM에 그대로 렌더링되어 트리를 깊게 만들고 스타일과 접근성에 부작용을 일으켰다. React 16에서 Fragment가 도입되면서 렌더링 결과에는 나타나지 않는 논리적인 묶음이 가능해졌다.

래퍼 div가 일으키는 대표적인 문제

  • 플렉스박스(Flexbox)나 그리드(Grid) 레이아웃에서 부모와 자식 사이에 끼어들어 정렬 규칙을 깨뜨린다.
  • table 요소 안에는 tr, td처럼 정해진 자식만 올 수 있으므로 div가 들어가면 유효하지 않은 HTML이 된다.
  • DOM 노드 수가 늘어나 메모리를 더 쓰게 되고 개발자 도구에서 구조를 파악하기도 어려워진다.

기본 사용법과 축약 문법

Fragment는 두 가지 방식으로 쓸 수 있다. 하나는 react 패키지에서 가져온 Fragment 컴포넌트를 명시적으로 사용하는 방식이고, 다른 하나는 빈 태그처럼 보이는 축약 문법이다. 두 방식 모두 렌더링 결과는 완전히 같다.

function Profile() {
  return (
    <>
      <h3>소개</h3>
      <p>프론트엔드 개발자입니다.</p>
    </>
  );
}

축약 문법은 짧고 읽기 쉽지만 어떤 속성도 붙일 수 없다는 제약이 있다. 속성이 필요한 순간, 특히 key를 지정해야 하는 순간에는 명시적인 Fragment 컴포넌트를 사용해야 한다.

key가 필요한 반복 렌더링

배열을 순회하며 형제 요소 쌍을 반복 렌더링할 때가 Fragment에 key를 지정하는 대표적인 상황이다. 예를 들어 용어와 설명을 dt, dd 쌍으로 출력하는 경우, 각 쌍을 div로 감싸면 dl의 콘텐츠 모델이 깨지므로 Fragment로 묶고 key를 부여한다.

import { Fragment } from 'react';

function Glossary({ items }) {
  return (
    <dl>
      {items.map((item) => (
        <Fragment key={item.id}>
          <dt>{item.term}</dt>
          <dd>{item.description}</dd>
        </Fragment>
      ))}
    </dl>
  );
}

key는 React가 재조정(reconciliation) 과정에서 각 항목을 식별하는 근거가 되므로 Fragment라고 해서 예외가 아니다. 현재 Fragment에 지정할 수 있는 속성은 key가 유일하다.

래퍼 요소와 Fragment 비교

구분래퍼 divFragment
실제 DOM 노드생성된다생성되지 않는다
CSS 레이아웃 영향부모와 자식 사이에 끼어든다영향이 없다
스타일과 이벤트 지정가능하다불가능하다
HTML 유효성table, dl 내부에서 깨질 수 있다문제가 없다
적합한 경우실제 묶음 컨테이너가 필요할 때문법 제약만 해결하면 될 때

주의할 점

  • Fragment는 DOM에 존재하지 않으므로 스타일, 클래스, 이벤트 핸들러를 붙일 수 없다. 시각적인 컨테이너가 필요하다면 의미에 맞는 실제 요소를 쓰는 것이 맞다.
  • 축약 문법에는 key를 포함해 어떤 속성도 줄 수 없으므로 반복 렌더링에서는 반드시 명시적 Fragment를 사용한다.
  • 모든 래퍼를 기계적으로 없애는 것이 목적이 아니다. 접근성 그룹화나 스타일 적용처럼 실제 역할이 있는 요소는 남겨야 한다.
  • 불필요한 래퍼를 줄이면 접근성 트리도 단순해져서 스크린 리더 사용자에게 전달되는 구조가 명확해진다는 부수 효과도 있다.

면접에서 이렇게 물어본다

  • JSX에서 컴포넌트가 루트 요소를 하나만 반환해야 하는 이유를 컴파일 관점에서 설명해 보라.
  • 래퍼 div 대신 Fragment를 써야 하는 구체적인 상황을 CSS 레이아웃과 HTML 유효성 측면에서 들어 보라.
  • 축약 문법과 명시적 Fragment의 차이는 무엇이고, key가 필요할 때는 어느 쪽을 써야 하는가.
  • Fragment가 실제 DOM과 재조정 과정에서 각각 어떻게 다루어지는지 설명해 보라.
React / Vue 문서 전체 보기

이 개념, 내 코드에서는 어떻게 물어볼까요

데브핏(DevFit)에 채용공고 URL을 붙여 넣고 레포지토리를 연결하면, 내가 쓴 커밋에서 예상 질문과 어필 포인트를 만듭니다. 하루 10회까지 무료입니다. 합불 판정이나 지원자 랭킹은 만들지 않고, 최종 판단은 사람이 합니다.

공고 넣고 시작하기