본문 바로가기

React

Transient Props를 사용해 styled-component 에러 해결하기

styled-components를 사용해 간단한 버튼을 만들었는데 콘솔에 처음 보는 에러가 찍혔다. styled-components를 자주 사용하지 않은 것도 있었겠지만 한 번도 발생해 본 적이 없는 에러였다. 에러의 내용은 다음과 같다.

 

해석하자면

경고: React는 DOM 요소에서 isSelected prop을 인식하지 못합니다. 만약 이것을 의도적으로 사용자 정의 속성으로 DOM에 표시하고 싶다면, 소문자 isselected로 철자를 맞추세요. 만약 부모 컴포넌트에서 실수로 전달한 것이라면, DOM 요소에서 제거하세요. 라는 뜻의 에러였다.

에러의 내용을 보고 조금 의아했다. '왜 prop을 인식하지 못하지? 소문자로 철자를 맞추라니 무슨 소리지? 오타는 없는데'라는 생각을 하였다. 원인에 대해 찾아보았고 사소한 걸 놓치고 있었다. 바로 styled-components에서 button 속성에 props를 내려주려고 했기 때문에 DOM에 접근할 수밖에 없는 것이었다.

즉, 이 경고는 React가 특정 prop(내가 작성한 코드에서는 isSelected)을 DOM 요소에 전달했기에 발생한 것이다. 기본적으로 React는 표준 HTML 속성이 아닌 커스텀 prop을 DOM 요소에 전달하지 않으므로, 이를 감지하면 경고를 표시한다.

이를 해결하기 위해 방법을 찾던 중 transient props에 대해 알게 되었다.

Transient Props란?

Transient Props는 styled-components에서 스타일링을 위해 전달되지만, DOM 요소에는 전달되지 않는 props다. 이를 통해 React가 인식하지 못하는 커스텀 props가 DOM에 의도치 않게 전달되어서 에러가 발생하는 것을 피할 수 있다.

 

그렇다면 Transient Props를 사용해서 에러를 어떻게 해결할 수 있을까?

사용방법은 다음과 같다. styled-component에서 스타일 적용을 위해 사용하는 props의 앞에 $를 붙여주면 된다. 이를 통해 해당 prop를 DOM에 전달하지 않는다.

 

다음은 에러를 직접 겪고 수정한 코드이다.

 

 

//SelectBox.tsx

//기존 코드
import { useState } from 'react';
import * as s from './style';

export default function SelectBox() {
  const [selected, setSelected] = useState(false);
  const onClick = () => {
    setSelected(!selected);
  };
  return (
    <s.SelectBoxContainer
      isSelected={selected}
      radius="4px"
      onClick={onClick}
    />
  );
}

//수정 후 코드
import { useState } from 'react';
import * as s from './style';

export default function SelectBox() {
  const [selected, setSelected] = useState(false);
  const onClick = () => {
    setSelected(!selected);
  };
  return (
    <s.SelectBoxContainer
      $isSelected={selected}
      $radius="4px"
      onClick={onClick}
    />
  );
}

 

//style.ts

//기존 코드
import { styled } from 'styled-components';

interface SelectBoxProps {
  radius: '4px' | '34px';
  isSelected: boolean;
}
export const SelectBoxContainer = styled.button<SelectBoxProps>`
  display: flex;
  width: 1.125rem;
  height: 1.125rem;
  border: 1.5px solid
    ${({ isSelected, theme }) => (isSelected ? theme.colors.main : '#868E96')};
  background-color: ${({ isSelected }) =>
    isSelected ? '#E8E3FD' : '#FFFFFF'};
  cursor: pointer;
  border-radius: ${(props) => props.radius};
`;

//수정 후 코드
import { styled } from 'styled-components';

interface SelectBoxProps {
  $radius: '4px' | '34px';
  $isSelected: boolean;
}
export const SelectBoxContainer = styled.button<SelectBoxProps>`
  display: flex;
  width: 1.125rem;
  height: 1.125rem;
  border: 1.5px solid
    ${({ $isSelected, theme }) => ($isSelected ? theme.colors.main : '#868E96')};
  background-color: ${({ $isSelected }) =>
    $isSelected ? '#E8E3FD' : '#FFFFFF'};
  cursor: pointer;
  border-radius: ${(props) => props.$radius};
`;

 

isSelected라는 prop앞에 $를 붙여주었고 오직 스타일링을 위한 prop으로 DOM에 접근하지 않게 됨으로 에러는 해결되었다.