[React] React.fragment의 사용법과 사용 이유
📑 개요
리액트를 처음 써보면 자주 하는 실수가 있다.
바로 return의 최상단 태그를 감싸주지 않아 오류가 나는 것......
처음 사용할 땐 이것 때문에 자주 버벅였다.
어 왜 안되지.. 어라.. 어? 하고 시간 날리다가 깨닫기를 세번 정도 반복하고서야 안 하는 실수...
🧶 React.Fragment
<React.Fragment>는 여러 요소를 그룹화할 때 사용하는 도구이다.
JSX에서는 최상단 태그를 통해 하나의 부모 요소로 감싼 후 return을 해줘야 한다.
컴포넌트가 렌더링 될 때 효율적인 비교를 위해 실제 DOM 트리는 하나의 구조로 이루어져야 한다.
이를 위해 fragment를 사용하여 컴포넌트가 렌더링될 때 실제 DOM에 별도의 노드를 추가하지 않고 여러 요소를 그룹화는 것이다.
참고로 <>는 <React.Fragment>의 축약형으로 용도의 차이는 없다.
그러나, React.Fragment를 사용할 때는 key 속성을 사용할 수 있다.
올바른 코드를 보기 전에 오류가 나는 코드를 먼저 보는 것이 이해가 쉬울 것 같다.
import React from 'react';
function MyComponent() {
return (
<h1>h1 태그입니다</h1>
<p>h1과 p태그는 합쳐지지 않은 채 return 되고 오류가 발생합니다.</p>
);
}
export default MyComponent;
이 때 오류 메세지는 이러하다.
Error: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?
JSX에서 인접 요소들이 하나의 부모 요소로 감싸져 있지 않아 발생하며, 이를 해결하기 위해 fragment의 사용이 필요하다.
- React.Fragment 코드
import React from 'react';
function MyComponent() {
return (
<React.Fragment>
<h1>h1 태그입니다.</h1>
<p>h1태그와 p태그가 React.Fragment라는 최상단 태그로 감싸져 있습니다.</p>
</React.Fragment>
);
}
export default MyComponent;
- Fragment 코드 (축약형)
import React from 'react';
function MyComponent() {
return (
<>
<h1>h1 태그입니다.</h1>
<p>h1태그와 p태그가 <>라는 최상단 태그로 감싸져 있습니다.</p>
</>
);
}
export default MyComponent;
만약 여기서 key의 사용이 필요하다면 축약형이 아닌 React.Fragment를 사용해야 한다.
리스트를 렌더링할 경우 key를 사용하는 경우가 많다.
코드 예시는 공식 문서에서 가져왔다.
function Glossary(props) {
return (
<dl>
{props.items.map(item => (
// React는 `key`가 없으면 key warning을 발생합니다.
<React.Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</React.Fragment>
))}
</dl>
);
}
🤷♀️ 어째서 Fragment를 사용할까?
굳이 최상단 태그를 감싸는 것이라면 왜 div와 같은 다른 태그가 아닌 Fragment 태그를 사용해야 하는지 의문이 들 것이다.
이 이유는, 불필요한 태그의 사용을 최소화하여 불필요한 DOM 노드를 생성하지 않기 위함이다.
- 불필요한 DOM 노드 생성의 문제점
- 성능 문제
추가적인 DOM 노드는 브라우저의 렌더링 성능에 영향을 미칠 수 있다. - 스타일링 문제
불필요한 div는 CSS 스타일링에 영향을 줄 수 있다. 예상치 못한 레이아웃 문제가 발생하거나 CSS 셀렉터가 복잡해질 수 있다. - 의미 없는 마크업
시맨틱(semantic)한 HTML을 유지하기 위해서다. 의미 없는 div는 HTML 구조를 복잡하게 만들고, 접근성(accessibility)을 저하시킬 수 있다.
만약 <div>를 통해 Fragment를 감싼다고 생각해보자.
import React from 'react';
function MyComponent() {
return (
<div>
<h1>Hello</h1>
<p>This is a paragraph.</p>
</div>
);
}
export default MyComponent;
이 경우 실제 HTML은 이런 식으로 보여진다.
<div>
<h1>Hello</h1>
<p>This is a paragraph.</p>
</div>
의미 없는 div 태그가 추가되어 있다.
하지만 Fragment로 감싸보자.
import React from 'react';
function MyComponent() {
return (
<>
<h1>Hello</h1>
<p>This is a paragraph.</p>
</>
);
}
export default MyComponent;
이 경우 HTML 태그는 아래와 같이 보여진다.
<h1>Hello</h1>
<p>This is a paragraph.</p>
이런 식으로 불필요한 태그가 추가되지 않고 DOM 구조가 깔끔해진다.
✨ 마무리
React 쓸 때 진짜 이거... 나는 실수 많이 했던지라...
그냥 만들어놓고 왜 안돼!~~~ 하기를 너무 많이 했던지라...
같이 하는 애들은 안 그랬지만... 나만 그랬지만...
다들 잊지 마쉬길...🥲~~~
- 요약
요약은 있을 때도 있고 없을 때도 있는 법..........................................
<> 만 알면 되잖아요!🤨 흥이다!
그렇다고 진짜 <>만 알면 되는구나 하심 안댑니다.................😬