[React] Fragments

2023. 7. 1. 23:19개발 공부/React

🔎들어가기 전


react로 개발할 때 아래와 같은 패턴을 많이 접했을 것이다.

return ( <>
...someting
</>
)

잘 알고 쓰고 있다면 베스트!

하지만, 나는 그냥
<></> 요렇게 감싸야 빨간 밑줄이 안쳐져서?
또는, 단순히 여러개의 엘리먼트들을 그룹화하고 싶을 때
사용하고 있었다.

그러던 중 아래와 같은 코드를 보게 되었다.

  <Fragment>
    ...someting
  </Fragment>

응? 이게 뭘까?

알고 보니 <></> 와 같은 의미였다.

제대로 모르고 그냥 쓰다보니
마치 계피와 시나몬이 다른 건 줄 아는 느낌이었다..^^;;...

그래서 이번 기회에 간단하더라도 짚고 넘어가자! 라는 의미로 포스팅하게 되었다.

📍Fragments란?

Fragment는 React v16에 추가된 기능으로,

DOM에 별도의 노드를 추가하지 않고 여러 자식을 그룹화한다.

즉, 쉽게 말해서

아래와 같이 여러개의 자식 엘리먼트들을 쓸 때
이것들을 반환해주기 위해서는 부모요소가 있어야하는데,

 render() {
 return (
   <React.Fragment>
     <ChildA />
     <ChildB />
     <ChildC />
   </React.Fragment>
 );
}

fragments는 별도의 부모 노드없이 자식 요소들을 그룹화하여 반환해준다.

위의 예시만으로는 이해가 안 될 수 있다.

✍️차이점을 비교해보면서 천천히 살펴보자!

💡Fragments를 안 썼을 경우


 const Table = () => {
 	  return (
     <table>
       <tr>
         <Columns />
       </tr>
     </table>
   );
 }  

table 요소 안에
테이블의 행을 표현해주는 tr태그와
Columns 라는 컴포넌트가 존재한다.

여기서 Columns 컴포넌트를 자세히 살펴보자

const Columns = () => {
render() {
  return (
    <div>
      <td>Hello</td>
      <td>World</td>
    </div>
  );
}

 Columns 컴포넌트는
여러개의 td 엘리먼트들로 이루어져있기 때문에
여러개의 자식들을 반환하기 위해
div라는 상위 엘리먼트로 한번 감싸주고 있다.

그럼 최종적으로 Table 컴포넌트는 어떻게 보여질까?

아래와 같은 형태가 된다.

<table>
<tr>
  <div> 💡의미없는 div!!!💡
    <td>Hello</td>
    <td>World</td>
  </div>
</tr>
</table>

의미없는 div로 한번 감싸져서 출력된다.

이렇게 의미없는 태그 작성을 해결해주는게 바로 Fragments다.

💡Fragments를 썼을 경우 뭐가 좋을까?


위에서 정의했던 Columns 컴포넌트를 Fragments를 사용하여 다시 정의해보자.

const columns = () => {
render() {
  return (
    <React.Fragment>
      <td>Hello</td>
      <td>World</td>
    </React.Fragment>
  );
}

div대신 Fragments사용했다.

그렇다면, 해당 컴포넌트를 사용하여 Table 컴포넌트를 출력해보자

<table>
<tr>
  <td>Hello</td>
  <td>World</td>
</tr>
</table>

더이상 불필요한 div태그가 들어가있지 않은 깔끔한 컴포넌트가 출력되었다.

따라서, Fragments의 장점 은!

  • 위의 div와 같이 불필요한 DOM node의 생성을 막기때문에 메모리를 적게 사용한다.
  • flexbox나 gridbox관계에 있는 엘리먼트 사이에
    를 추가하게 되면 레이아웃을 유지하기 어려울 때 사용하면, 레이아웃을 유지한 채로 엘리먼트들을 반환할 수 있다.

💡Fragment 꿀팁!


const columns = () => {
render() {
  return (
    <React.Fragment>
      <td>Hello</td>
      <td>World</td>
    </React.Fragment>
  );
}

가 아니라

const columns = () => {
 render() {
   return (
    <>
       <td>Hello</td>
       <td>World</td>
     </>
   );
 }

요렇게 간단하게 작성할 수 있다!
대부분 현업에서 이렇게 쓰고 있다.
실제로 회사 프로젝트에서도 Fragment를 직접적으로 명시해서 쓰는 경우는 거의 못봤다.

📌 사용 시 주의사항

Fragments는 따로 attribute가 필요하지 않지만,
유일하게 key 속성 요구한다.

map을 이용하여 배열 어트리뷰트들을 나열하는 경우가 많은데, 이때 Fragments를 사용한다면 아래와 같이 key값을 명시해줘야한다.
안그러면 key props을 써달라는 경고문이 브라우저 콘솔에 도배해놓을 것이다!

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

🧷참고자료