리액트를 사용한 프로젝트를 진행하면서 의미없는
<div>
를 정의한 코드가 많았다. 끝없는 div 지옥, 어떻게 해결해야 할까?
React에서 컴포넌트가 여러 엘리먼트를 반환하는 것은 흔한 패턴이다. Fragments
는 DOM에 별도의 노드를 추가하지 않고 여러 자식을 그룹화할 수 있다.
render() {
return (
<React.Fragment>
<ChildA />
<ChildB />
<ChildC />
</React.Fragment>
);
}
또한 단축 문법(
<></>
)으로 사용할 수 있다.render() { return ( <> <ChildA /> <ChildB /> <ChildC /> </> ); }
Fragment
를 사용해야 하는 이유는 <table>
예시를 들면서 알아보자!
//Table 컴포넌트
class Table extends React.Component {
render() {
return (
<table>
<tr>
<Columns />
</tr>
</table>
);
}
}
//Columns 컴포넌트
class Columns extends React.Component {
render() {
return (
<div>
<td>Hello</td>
<td>World</td>
</div>
);
}
}
렌더링 된 HTML이 유효하려면 <Columns />
컴포넌트가 여러 <td>
엘리먼트만 반환해야 한다. <Columns />
의 render() 안에 부모 div로 자식들을 감싼다면 렌더링 된 HTML은 유효하지 않게 된다.
<Table />
출력 결과 ↓<table>
<tr>
<div>
<td>Hello</td>
<td>World</td>
</div>
</tr>
</table>
<Table />
출력 결과 ↓//Fragments를 사용한 Columns 컴포넌트
class Columns extends React.Component {
render() {
return (
<React.Fragment>
<td>Hello</td>
<td>World</td>
</React.Fragment>
);
}
}
// Table 컴포넌트 출력 결과
<table>
<tr>
<td>Hello</td>
<td>World</td>
</tr>
</table>
💡 실제 적용 (Key가 있는 Fragments)
Fragments
에key
가 있다면<React.Fragment>
문법으로 명시적으로 선언해야 한다.
예를 들어 정의 목록을 만들기 위해 컬렉션을 fragments 배열로 매핑하는 사용 사례이다.<ul className="stars"> {[1, 2, 3, 4, 5].map(index => { return ( <React.Fragment key={index.id}> <Star index={index} onClick={() => onClick(index - 0.5)} onMouseEnter={() => onMouseEnter(index - 0.5)} onMouseLeave={onMouseLeave} width="20px" fill={ setRating < index - 0.5 ? setHoverRating < index - 0.5 ? '#eeeeee' : '#FEDD63' : '#FEDD63' } /> <Star index={index} onClick={() => onClick(index)} onMouseEnter={() => onMouseEnter(index)} onMouseLeave={onMouseLeave} width="20px" style={rightStyle} fill={ setRating < index ? setHoverRating < index ? '#eeeeee' : '#FEDD63' : '#FEDD63' } /> </React.Fragment> ); })} </ul>
진행했던 프로젝트에서 영화 상세 페이지에 별점을 매기는 부분의 컴포넌트 이다. 별점을 보여주기 위해 1~5번의 index를 갖는
<Star />
컴포넌트를 map함수로 별을 만들었다.
컴포넌트 내에 의미 없는<div>
대신 Fragments를 사용하였고 각 key값을 넣기 위해 단축 문법이 아닌<React.Fragment>
문법을 사용했다!