Next.js와 shadcn/ui에서 DropdownMenuTrigger의 asChild 속성에 대해 알아보기 🚀
Next.js와 shadcn/ui에서 DropdownMenuTrigger의 asChild 속성에 대해 알아보기 🚀 안녕하세요! 이번 포스트에서는 Next.js에서 shadcn/ui패키지의 컴포넌트를 사용할 때 등장하는 속성에 대해 살펴보려 합니다. “이 속성은 언제 써야 하고, 왜 필…
Next.js와 shadcn/ui에서 DropdownMenuTrigger의 asChild 속성에 대해 알아보기 🚀
안녕하세요! 이번 포스트에서는 Next.js에서 shadcn/ui 패키지의 DropdownMenuTrigger 컴포넌트를 사용할 때 등장하는 asChild 속성에 대해 살펴보려 합니다.
“이 속성은 언제 써야 하고, 왜 필요한 걸까?”라는 의문을 해결해봅시다! 🧐
asChild란? 🤔
Radix UI 기반의 DropdownMenuTrigger 컴포넌트(이를 확장한 shadcn/ui도 마찬가지)는 기본적으로 내부에서 <button> 태그를 만들어 제공합니다.
하지만 때로는 Link, div 혹은 CustomButton 같이 내가 원하는 컴포넌트를 그대로 트리거로 쓰고 싶을 때가 있죠.
그럴 때 asChild를 사용하면, 기본 <button> 래퍼를 생성하지 않고, 내가 전달한 컴포넌트 자체를 트리거로 사용하게 됩니다.
-
DOM 구조가 복잡하게 중첩되지 않아, 깔끔한 마크업을 유지할 수 있어요.
-
<button>태그와 스타일이 충돌하거나,<Link>와 겹치는 문제도 해결할 수 있어요.
언제 / 왜 사용해야 할까? 🔍
특정 DOM 태그로 감싸지 않고 싶을 때
기본 <button> 대신에 내가 전달한 컴포넌트가 직접 트리거가 되길 원할 때 사용합니다.
불필요한 DOM 계층을 제거하고 싶을 때
<button> 태그가 추가로 생기는 걸 원치 않는다면 asChild로 중첩 구조를 없앨 수 있습니다.
스타일 겹침을 피하고 싶을 때
button 태그 위에 또 버튼 스타일이 덧씌워지는 문제를 방지하고, 원하는 스타일링을 그대로 가져갈 수 있습니다.
하이드레이션(Hydration) 문제를 방지하고 싶을때
nextjs에서는 <button>태그안에 <button>을 추가하면 하이드레이션 문제가 발생합니다. 이는 인터랙티브 컨텐츠를 겹쳐서 사용하면 안되는 문제 때문입니다.
Interactive Content cannot be nested (<a> nested in a <a> tag, <button> nested in a <button> tag, etc.)
asChild를 안 썼을 때, html tag 구성
<button>
<button>
...
</button>
</button>
asChild를 썼을 때, html tag 구성
<button>
...
</button>
코드 예시 💻
아래 예시에서는 DropdownMenuTrigger에 asChild를 설정하여, Link 태그를 그대로 트리거로 사용하고 있습니다.
import Link from 'next/link'
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
} from "@/components/ui/dropdown-menu"
export default function Demo() {
return (
<DropdownMenu>
{/* asChild로 Link 자체를 트리거로 사용합니다. */}
<DropdownMenuTrigger asChild>
<Link href="/">
홈으로
</Link>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>메뉴 1</DropdownMenuItem>
<DropdownMenuItem>메뉴 2</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)
}
asChild옵션을 제거한다면,Link바깥에<button>이 다시 생기면서 중복 DOM 구조가 형성될 것입니다.
마치며 ✨
asChild는 작지만 꽤나 유용한 속성입니다.
props를 “넘겨서 끝내는” 것만으로는 해결되지 않는, DOM 중첩 문제나 스타일 충돌 등을 말끔히 해결해주죠.
- 핵심 포인트: “내가 직접 지정한 컴포넌트를 DOM에 그대로 렌더링하면서도, DropdownMenu 트리거 역할을 하게 만들고 싶을 때
asChild를 사용하라!”
참고 자료 📚
읽어주셔서 감사합니다! 더 궁금하신 점이 있으시면 언제든 댓글이나 문의 부탁드려요. 🙌