[ React ] styled-component에 props 보낼 때 나오는 warning 해결

·2023년 8월 10일
6

React

목록 보기
18/21
post-thumbnail
post-custom-banner

[ 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 lowercase isactive 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에서 스타일링에만 그치도록 하기 위한 $ 접두사 붙이기!

warning 해결

[ 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;
`;
profile
개발을 개발새발 열심히➰🐶
post-custom-banner

0개의 댓글