컴포넌트가 렌더링 될 때마다 validateDomNesting이라는 HTML 유효성 검사 전용 모듈에 의해 유효성 검사를 수행한다. 이 유효성 검사는 자식 → 부모 태그 계층 구조의 검증을 의미하는 데, 쉽게 말하자면 li 태그 안에 ul 태그가 들어 있는 것처럼 잘못된 중첩이 없는지 다시 확인 해주는 것이라고 생각하면 된다.
이중 생각지 못하게 자주 발생하는 에러는
- <a> cannot appear as a descendant of <a>
- <p> cannot appear as a descendant of <p>
- <button> cannot appear as a descendant of <button>
등 이 있다.
나 또한 button 태그 안에 button 태그가 중첩되어있다는 에러가 떴는데 문제는 그 어느곳에서도 button 태그를 중첩 시킨 적이 없다는 것이었다.😂
나는 ui 컴포넌트 라이브러리 shadcn/ui 를 사용하고 있었고 아이콘 hover 시 설명이 나오는 tooltip과 클릭 시 dropdown이 필요해서 두가지 컴포넌트를 중첩해서 사용하고 있었다.
이때 trigger 컴포넌트가 HTMLButtonElement 였고 두가지 trigger가 중첩되어있었기 때문에 button 태그 안에 button 태그가 중첩되어있다고 나왔던 것이다.
asChild props를 전달하면 된다.
return (
<DropdownMenu>
<DropdownMenuTrigger>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<CheckCheck />
</TooltipTrigger>
<TooltipContent>
<p>상태 변경</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</DropdownMenuTrigger>
<DropdownMenuContent>
{Status?.map(({ label, value }: { label: string; value: string }) => (
<DropdownMenuItem
key={value}
onClick={() => changeUserStatus(value)}
>
<p>{label}</p>
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
)
위의 예시를 보면 DropdownMenuTrigger안에 TooltipTrigger가 중첩되어 있다.
이때 TooltipTrigger에 asChild 속성을 부여하여 DropdownMenuTrigger의 자식으로 만들면서 문제를 해결할 수 있었다.