"매 component 의 root 의 wrapper div 의 elimination". React Fragment (<>...</> 또는 <Fragment>) 매 component 매 multiple sibling roots 의 return 의 enable — 매 unnecessary <div> wrapper 의 avoid. "Fragment-bound" component 매 single DOM root 의 not-have, 매 layout (Grid, Table, Flex) 매 fragile 의 implication 의 carry.
매 핵심
매 Why Fragment
DOM cleanliness: 매 wrapper div 의 CSS Grid/Flex 의 break — 매 child 매 grid item 의 directly 의 must be.
No semantic noise: 매 <table> 매 <tr> 매 <td> 의 nest 의 wrapper div 의 invalid HTML.
Performance (marginal): 매 fewer DOM nodes — 매 hot lists 의 measurable.
매 Forms
<></> — short syntax, 매 no key/props.
<Fragment key={...}> — 매 list iteration 매 key 의 needed 시.
<React.Fragment> — explicit import, 매 build tooling 의 short syntax 의 not-support 시.
매 Fragment-bound implications
매 ref 의 attach 의 not-possible (매 single DOM node 의 not-have).
매 parent 매 child layout 의 control 의 must — 매 child 매 own root 의 not-have.
functionGreeting() {return(<><h1>Hello</h1><p>World</p></>);}// 매 DOM 의 <h1>+<p> 의 sibling, 매 no wrapper
Fragment with key (list)
import{Fragment}from'react';functionGlossary({items}:{items:{term: string;def: string}[]}){return(<dl>{items.map(it=>(<Fragmentkey={it.term}><dt>{it.term}</dt><dd>{it.def}</dd></Fragment>))}</dl>);}// 매 short syntax 매 key prop 의 not-accept — 매 explicit Fragment 의 use
Table row composition
functionProductRow({product}:{product: Product}){return(<><td>{product.name}</td><td>{product.price}</td><td>{product.stock}</td></>);}functionProductTable({products}:{products: Product[]}){return(<table><tbody>{products.map(p=>(<trkey={p.id}><ProductRowproduct={p}/></tr>))}</tbody></table>);}// 매 wrapper div 매 tr 안 의 invalid HTML — 매 Fragment 의 only correct
CSS Grid items
functionGridGroup() {return(<><divclassName="grid-item">A</div><divclassName="grid-item">B</div><divclassName="grid-item">C</div></>);}functionLayout() {return(<divstyle={{display:'grid',gridTemplateColumns:'repeat(3, 1fr)'}}><GridGroup/>{/* 매 3 children 의 grid items 의 directly */}</div>);}// 매 wrapper div 의 add 시 매 single grid cell 의 collapse
// 매 X — Fragment 매 ref 의 not-attach 의
constBad=forwardRef<HTMLDivElement>((props,ref)=>(<><h1ref={ref}>Title</h1>{/* 매 child element 의 ref 의 forward 의 must */}<p>Body</p></>));// 매 O — 매 explicit child 의 ref 의 forward
constCard=forwardRef<HTMLHeadingElement,{title:string;body:string}>(({title,body},ref)=>(<><h1ref={ref}>{title}</h1><p>{body}</p></>),);
Suspense / ErrorBoundary 매 Fragment children
functionApp() {return(<Suspensefallback={<Spinner/>}><><Header/><Main/><Footer/></></Suspense>);}// 매 Suspense 매 single child 의 not-require — 매 Fragment 의 N children 의 all 의 wait
Slot pattern 의 fragment-aware
typeSlotProps={children: ReactNode};functionSlot({children}:SlotProps){// 매 children 매 Fragment 매 single 매 multiple 매 unwrap 의 logic
if(isValidElement(children)&&children.type===Fragment){return<>{children.props.children}</>;}return<>{children}</>;}
매 결정 기준
상황
Approach
Component 매 단일 root 의 natural
매 <div> 의 use
Wrapper div 매 layout 의 break
매 Fragment
Table / dl / select children
매 Fragment 의 mandatory
List item with multiple roots
매 Fragment with key
Ref / styling 의 root needed
매 div / specific element 의 use
기본값: 매 wrapper 매 semantic value 의 carry 의 div, 매 그렇지 않으면 매 Fragment.
언제: 매 multi-root component. Table/Grid layout 의 wrapper 의 break 의 시. List item 매 multiple sibling 의 render.
언제 X: 매 single root + ref/styling needed — 매 div 의 use. Wrapper 의 styling target 의 expected 시.
❌ 안티패턴
Wrapper div habit: 매 모든 component 매 <div> 의 wrap — 매 div soup, 매 layout 의 fragile.
Fragment without key in list: 매 <> 매 .map 안 의 use — 매 React warning + reconciliation 의 broken.
Trying to ref a Fragment: 매 Fragment 의 DOM node 의 not-have — 매 forwardRef 의 specific child 의 forward 의 must.
Fragment inside single-child API: 매 some libs (older) 매 single child 의 expect — 매 Fragment 의 expand, 매 break.