[ Header.tsx ]
<S.MenuItem
key={item.title}
isActive={
item.path === location.pathname ||
item.subMenu?.some(
(subItem) => location.pathname === subItem.path,
)
}
>
{item.title}
</S.MenuItem>
[ Header.styles.ts ]
export const MenuItem = styled.div<{ isActive: boolean | undefined }>`
display: flex;
align-items: center;
width: fit-content;
height: 100%;
position: relative;
border: none;
background-color: transparent;
color: ${(props) =>
props.isActive ? `${colors.black[1000]}` : `${colors.brown[700]}`};
font-size: ${font.fontSize[100]};
font-weight: 700;
cursor: pointer;
`;
Warning: React does not recognize the
isActive
prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercaseisactive
instead. If you accidentally passed it from a parent component, remove it from the DOM element.
isActive라는 값을 styled-component에 보내주는데 위와 같은 경고 문구가 떴다.
무슨 경고인가 싶어 Chat GPT에게 물어보니...
경고 메시지가 나타나는 이유는, DOM 요소에 대한 사용자 정의 속성이 React에 의해 대문자로 시작할 수 없기 때문입니다. 여기서 isActive라는 prop을 스타일링에 사용하고 있으며, 이는 HTML 태그에 직접 연결되지 않아야 합니다.
styled-components를 사용하면서 이 문제가 발생하는 경우, 해당 prop을 스타일드 컴포넌트 내부에서만 사용하고 HTML 요소에 전달되지 않도록 해야합니다. 이렇게 하려면 $ 접두사를 사용하여 해당 prop을 transient prop으로 만들면 됩니다.
그래서 $ 접두사를 왜 사용하는데...?
$ 접두사를 사용하면 해당 prop이 "transient" prop임을 나타냅니다. 이 접두사가 있는 prop은 styled-component로 전달되지만, 실제 HTML 요소로 전달되지 않습니다. 이는 React가 경고를 표시하지 않도록 하고, 렌더링된 HTML에서 불필요한 속성을 제거해줍니다.
이 prop은 스타일링을 위해 MenuItem 컴포넌트에 전달되지만, 렌더링 된 HTML에는 나타나지 않습니다.
이렇게 하면 React 경고를 방지하고, 최종 HTML이 깔끔하게 유지되며, 브라우저가 이해하지 못하는 속성을 실수로 HTML 요소에 전달하는 것을 방지할 수 있습니다.
정말 처음 알게 된 사실이다...ㅎㅎ
HTML 요소까지 닿지 않고 styled-component에서 스타일링에만 그치도록 하기 위한 $
접두사 붙이기!
[ Header.tsx ]
<S.MenuItem
key={item.title}
$isActive={
item.path === location.pathname ||
item.subMenu?.some(
(subItem) => location.pathname === subItem.path,
)
}
>
{item.title}
</S.MenuItem>
[ Header.styles.ts ]
export const MenuItem = styled.div<{ $isActive: boolean | undefined }>`
display: flex;
align-items: center;
width: fit-content;
height: 100%;
position: relative;
border: none;
background-color: transparent;
color: ${(props) =>
props.$isActive ? `${colors.black[1000]}` : `${colors.brown[700]}`};
font-size: ${font.fontSize[100]};
font-weight: 700;
cursor: pointer;
`;