If haven't migrated your styling to use transient props ($prefix), you might notice React warnings about styling props getting through to the DOM in v6.
styled-components 공식문서 - What do I need to do to migrate to v6
styled-components는 v6부터 기본값으로 들어가던 shouldForwardProp을 제거했다. 그리고 Transient props를 기본적으로 사용하길 원하는 듯하다.
마이그레이션을 진행해 본 사람들은 모두, props를 사용하는 곳에서 React의 경고와 styled-components에서의 경고가 함께 뜨는 경험을 했을 것이다.
결론부터 말하자면,
바로 직접적으로 사용할 styled-component만 Transient props를 사용해야 한다.
만약 해당 컴포넌트가 Base Component처럼 HOC에 포함될 수 있는 경우라면, shouldForwardProp을 사용해야 한다.
const SelectAllCheckbox = () => {
...
return <CheckAllCheckbox $fixedWidth={50} />;
};
function CheckAllCheckbox(props) {
...
return <StyledCheckboxCell {...props} />;
}
const StyledCheckboxCell = styled(CheckboxCell)`
@media ${({ theme }) => theme.devices.mobile} {
min-width: 30px;
}
`;
export const CheckboxCell = ({ className, ...restProps }) => {
...
return (
<TableHead align='center' className={className} {...restProps}>
// ...
</TableHead>
);
};
export const TableHead = styled('th')(({ $fixedWidth }) => ({
padding: '0.4rem',
...($fixedWidth && { width: $fixedWidth + 'px', minWidth: $fixedWidth + 'px' }),
}));
최종적으로 $fixedWidth
가 사용되는 곳
: TableHead
styled 컴포넌트
$fixedWidth
전달 경로
: SelectAllCheckbox
=> CheckAllCheckbox
=> StyledCheckboxCell
=> CheckboxCell
=> TableHead
styled 컴포넌트
1. TableHead
2. CheckboxCell
을 감싼 StyledCheckboxCell
위 코드는 TableHead
컴포넌트에서 사용한 $fixedWidth
props를 SelectAllCheckbox
에서 부터 내려주고 있다.
이 코드를 작성한 사람은 $fixedWidth
가 CheckAllCheckbox
와 CheckboxCell
에서
props를 다 넘겨줬으니 당연히 props가 전달됐을 것이라 생각할 수 있다.
그리고 StyledCheckboxCell
에서 작성한 스타일은 CheckboxCell
에서 className를 통해 잘 들어갔을 것이다.
하지만, 코드를 실행해 보면 $fixedWidth
와 관련된 코드가 추가되지 않은 것을 확인 할 수 있을 것이다.
그리고 급히, console을 찍어보면, CheckAllCheckbox
의 props에는 $fixedWidth
가 있지만 CheckboxCell
에서는 props에 $fixedWidth
가 없다. 😱
자, 다시 공식 문서로 돌아가 Transient props에 대해 알아보자.
styled-components 공식문서 - Transient props
공식 문서에 적힌 것처럼 똑똑한 styled-component는 $
로 시작하는 props를 제거한다. 하지만 마지막으로 만난 styled에서 이것이 작동하는 것이 아니다. styled를 만나면 바로 $
로 시작하는 props를 제거하고 아래 React node나 DOM에서 사용되는 것을 방지하는 것이다.
코드에서 보면 StyledCheckboxCell
에서 style을 CheckboxCell
에 추가할 때, $fixedWidth
가 제거된 것이다.
그렇다면, 방법이 없는 것일까?
그럴 리가, 이때 shouldforwardprop
를 사용하면 된다.
styled-components 공식문서 - shouldforwardprop
const SelectAllCheckbox = () => {
return <CheckAllCheckbox fixedWidth={50} />;
};
function CheckAllCheckbox(props) {
return <StyledCheckboxCell {...props} />;
}
const StyledCheckboxCell = styled(CheckboxCell)`
@media ${({ theme }) => theme.devices.mobile} {
min-width: 30px;
}
`;
export const CheckboxCell = ({ className, ...restProps }) => {
return (
<TableHead align='center' className={className} {...restProps}>
// ...
</TableHead>
);
};
export const TableHead = styled('th').withConfig({
shouldForwardProp: prop => !['fixedWidth'].includes(prop),
})(({ fixedWidth }) => ({
padding: '0.4rem',
...(fixedWidth && { width: fixedWidth + 'px', minWidth: fixedWidth + 'px' }),
}));
언제나 그렇듯 공식 문서를 잘 읽자. 마이그레이션 시에는 어디에서 문제가 생길지 모르니, 확실히 변경되는 부분에 대해 잘 읽어보자.