-
Styled-Component에서는 id props를 사용할 수 없나요?Studying/React 2023. 6. 27. 23:58
문제 발생
Stack-Overflow 홈페이지 클론 코딩 중, 오른쪽 사이드 바 UI를 구현하던 중 styled-component의 id props가 인식되지 않았습니다.
Widget 컴포넌트는 아래와 같이 WidgetProps를 인자로 받아 위젯을 생성합니다.
const Widget = ({id, type, isstuck, title, children}:WidgetProps) => { return( <WidgetContainer type={type} id={id} isstuck={isstuck}> <WidgetHeader type={type}>{title}</WidgetHeader> {children} </WidgetContainer> ) }
여기서 <WidgetContainer> 가 바로 문제를 발생시키는 Styled-Component 입니다.
<WidgetContainer>는 type, id, isstuck 세 가지 인자를 받습니다.
그 중 id 인자는 Widget이 map으로 호출될 경우 몇 번째 위젯인지 알기 위해 사용됩니다.
const WidgetContainer = styled.div<{type:string|undefined, id:number, isstuck:boolean|undefined}>` border-radius: ${props.id !== 1 && '0'}; border-top: ${props.id !== 1 && '0px'}; `
그런데 여기서 문제가 발생했습니다.
<WidgetContainer>의 id props에 다음과 같은 에러가 발생했습니다.
(property) id : never 이 호출과 일치하는 오버로드가 없습니다. 오버로드 1/2(
'(props: { slot?: string; style?: CSSProperties; title?: string; ref?: Ref<HTMLDivElement>; key?: Key; defaultChecked?: boolean; defaultValue?: string | number | readonly string[]; ... 257 more ...; isstuck: boolean; } & Partial<...> & { ...; } & { ...; }): ReactElement<...>'
)에서 다음 오류가 발생했습니다.
'number' 형식은 'never' 형식에 할당할 수 없습니다. 오버로드 2/2(
'(props: StyledComponentPropsWithAs<"web", "div", { type: string; id: number; isstuck: boolean; }, never, "div">): ReactElement<StyledComponentPropsWithAs<"web", "div", { type: string; id: number; isstuck: boolean; }, never, "div">, string | JSXElementConstructor<...>>'
)에서 다음 오류가 발생했습니다.id 에 대한 타입을 number로 명시해 주었는데 왜 never 형식이라는 것일까요?
Styled-Component에서는 id props를 사용할 수 없다?
저 에러를 처음 마주했을 때 가장 먼저 never 타입이 무엇인지 알아보았습니다.
never 타입이란, 어떤 값도 가질 수 없는 값 입니다.
(아래 두 블로그 모두 동일한 원문을 번역한 것 같으나, 설명의 디테일이 달라서 둘 다 읽어보는 것도 좋을 것 같습니다.)
왜 id 는 이런 타입을 가지는 걸까요?
원인은 아래 주소에서 찾아볼 수 있었습니다.
저와 동일한 문제에 대한 질문글은 아닌데요,
The component styled.div with the id of "sc-fzqAui" has been created dynamically.
라는 부분에서 해답을 찾을 수 있었습니다.
게시자 분이 생성한 id="sc-fzqAui" 인 styled.div가 동적으로 생성된다는 에러가 발생한 것입니다.
여기서 다음 특징을 바로 알 수 있었습니다.
styled-component는 자동으로 string 타입의 id가 props로 생성된다.
저 또한 함수형 컴포넌트 안에 styled-component를 정의해서 dynamically 호출에 대한 에러를 받았었는데요, 그때 id 라는 것에 크게 초점을 두지 않아서 id 자동 생성에 대해서는 알 수 없었습니다.
생각해보면 styled-component를 개발자 도구로 클릭 해보았을 때 아래와 같이 class 가 자동 생성되는 건 알고 있었습니다. 그래서 id 로 구분되지 않고 오직 class로만 styled-component가 구분되어 생성되는 줄 알았습니다.
이 부분에 대해서는 어째서 개발자 도구로 클릭했을 땐 id 가 나오지 않는지 알아내지 못 했습니다.
그 대신 자동으로 string 타입의 id가 props로 생성된다. 라는 것에 대해서는 아래와 같이 증명할 수 있었습니다.
const WidgetContainer = styled.div<{type:string|undefined, isstuck:boolean|undefined}>` border-radius: ${props.id !== "1" && '0'}; border-top: ${props.id !== "1" && '0px'}; `
이렇게 props로 정의하지 않는 id를 string 타입으로 사용해도 아무런 에러가 발생하지 않는다는 점 입니다.
다만 id 값은 제가 원하는 string이 될 수 없으니 조건부 CSS를 적용할 수 없겠지만요. 당장 에러만 나지 않는다는 걸 보아 정의하지 않는 id 값을 가지는 건 확실한가 봅니다.
이는 id 뿐만 아니라 key, title, style 과 같은 기본 속성들에 대해서도 동일한 것 같습니다. 정의하지 않은 key, title, style props 또한 string 타입으로 사용하는 것에 아무런 에러가 나타나지 않네요.
└▷ 그런데 우리가 주로 '기본 속성' 이라고 하는 모든 속성에 대해서 string 값을 자동으로 생성하는 건 아닙니다.(ref, class 등은 안 됨)
제가 경험한 바 key는 굳이 styled-component가 아닌 map으로 호출한 React Component에서도 unique key값은 props로 인식이 안 됩니다. 그래서 동일한 unique 값을 id props로 넘겨줘 사용했던 기억이 납니다. 그와 같은 원리인지는 모르겠습니다.
그럼 위에서 본 화면 캡쳐에서 자동으로 생성된 class 이름이 id 값으로도 생성되는지 문득 궁금해졌습니다.
background-color: ${(props)=>props.id === 'sc-iUXMdM' && '#780404'};
그래서 특정 styled.div 의 class를 따와 조건이 참인지 확인해 봤지만 다른가보네요. 애초에 never 타입이라고 하였으니 정말 아무런 값이 없어야 하는 거 아닌가 싶은데 string 타입은 또 가능하고, 이것저것 앞뒤가 맞지 않는 것 같네요. 더 정확한 이유를 알고싶으나 지금은 일단 알게 된 것만 적어봅니다.
그러면, string 타입의 id를 자동 생성한다고 했으니까 string 타입의 값을 id 인자에 넣어주면 인식하지 않을까? 싶어서
const WidgetContainer = styled.div<{type:string|undefined, isstuck:boolean|undefined}>` background-color: ${(props)=>props.id}; ` const Widget = ({id, type, isstuck, title, children}:WidgetProps) => { return ( <WidgetContainer type={type} id='#780404' isstuck={isstuck}> ... </WidgetContainer> ) }
이렇게 직접 값을 줘 봤더니 styled.div에서 id 인자를 명시해주지 않아도 전달한 색상 값이 적용 되네요.
이렇게 배경색이 잘 변합니다.
그리하여 저의 결론은 기본 생성되는 속성은 props로 사용하지 말자. 입니다.
추가로 배울 만한 정보
앞서 styled-component의 경우 class가 자동으로 생성된다고 했는데요, 이에 대해 styled-components가 어떻게 작동하는지 더 자세히 설명해주는 글을 찾을 수 있었습니다.
보통 내부 동작 원리 같은 건 잘 찾기 힘들고, 대충 고개를 끄덕이며 쓰기 십상인데 너무 좋은 자료라고 생각됩니다.
'Studying > React' 카테고리의 다른 글
API 요청 코드 분리하기(일반 함수 vs 커스텀 훅) (0) 2023.07.06 [Storybook] Storybook + Twin.macro 환경 설정 (0) 2023.07.01 twin + styled 동적 할당 시 tw 사용이 불가능한 이유 (0) 2023.07.01 디자인 시스템을 기반으로 Storybook을 작성해보자 (0) 2023.05.24 Styled-Components 사용하고 CSS 파일을 줄여보자 (0) 2023.05.15