1. 현재 구조
Typography 프리셋을 함수형 컴포넌트로 정의하고, 내부에서 공통 Typography 컴포넌트에 스타일 props를 주입하는 방식.
const Typography = ({ children, ...props }) => (
<StyledTypography {...props}>
{children}
</StyledTypography>
);
const StyledTypography = styled.div`
font-family: 'SUIT', sans-serif;
margin: 0;
font-size: ${({ $fontSize }) => $fontSize};
...
`;
// 프리셋
export const Medium2Body2 = (props) => (
<Typography fontSize="15px" {...props} />
);
현재 구조의 특징
- 구조
- 함수형 컴포넌트가 스타일 프리셋 역할을 함
- 공통 Typography에 props를 주입하는 형태
장점
- margin, padding 등 커스텀 prop을 받아 로직 처리하기 편함
- 조건부 스타일 처리에 유연함
단점
- as 사용 시 forwardedAs를 써야 하는 등 사용성이 복잡함
- styled(Medium2Body2)처럼 재확장할 때 주의 필요
- 프리셋마다 함수 래퍼가 늘어나 코드가 장황해짐
2. 개선된 구조
프리셋을 순수 styled-component로 정의하고,
공통 Typography 컴포넌트에 .attrs()를 사용해 프리셋 값을 주입하는 방식.
const Typography = styled.div`
font-family: 'SUIT', sans-serif;
margin: 0;
/* 기본 폰트 속성 */
font-size: ${({ fontSize }) => fontSize || '15px'};
font-weight: ${({ fontWeight }) => fontWeight || 400};
line-height: ${({ lineHeight }) => lineHeight || '150%'};
letter-spacing: ${({ letterSpacing }) => letterSpacing || '-0.3px'};
/* 스타일링 속성 */
${({ color }) => color && `color: ${color};`}
${({ align }) => align && `text-align: ${align};`}
${({ margin }) => margin && `margin: ${margin};`}
${({ padding }) => padding && `padding: ${padding};`}
`;
프리셋 정의 예시
export const Bold1Header = styled(Typography).attrs({
as: 'h1',
fontSize: '36px',
fontWeight: 700,
lineHeight: '130%',
letterSpacing: '-0.72px',
})``;
Bold1Header.displayName = 'Bold1Header';
3. 개선된 구조의 장단점
장점
- 함수 래퍼 제거로 코드가 간결해짐
- as 사용 시 바로 태그 변경 가능
- styled(Bold1Header) 형태의 재확장이 직관적
- 프리셋 정의가 선언적으로 보이고 예측 가능
- Typography 시스템을 디자인 토큰처럼 관리 가능
단점
- 동적 로직 추가가 상대적으로 불편함
- fontSize 같은 커스텀 prop을 쓰려면
- ${props => props.fontSize} 또는 .attrs()를 직접 정의해야 함
4. .attrs()란?
.attrs()는 styled-components 라이브러리에서 제공하는 고유한 메서드로,
컴포넌트에 기본 props 또는 계산된 props를 미리 주입할 수 있다.
적용 대상
- styled-component에만 사용 가능
5. .attrs()로 설정할 수 있는 속성 종류
- HTML 표준 속성
- href, src, type, placeholder 등
- React 표준 속성
- id, onClick, onChange 등
- styled-components 특수 속성
- as
- 사용자 정의 Custom Props
- color, fontSize, active 등
- 스타일 로직에서 ${props => ...} 형태로 사용 가능
6. .attrs() 기본 사용법
선언 시점
const Box = styled.div.attrs(props => ({
bg: props.isActive ? 'red' : 'blue',
}))`
background: ${props => props.bg};
`;
- props는 실제 렌더링 시 전달되는 props
- <Box isActive /> → attrs 내부 로직이 실행됨
사용 시점
const App = () => {
const [isActive, setIsActive] = useState(true);
return <Box isActive={isActive} />;
};
7. .attrs() 사용 시 장점
1) 로직 분리
- React 컴포넌트: 상태, 데이터, 이벤트 관리
- Styled Component: 화면 표현과 스타일 책임
2) Default Props 역할
const PasswordInput = styled.input.attrs({
type: 'password',
})``;
// 사용
<PasswordInput />
8. .attrs() 종합 예시
styled.input.attrs({
// 1. HTML 속성
type: 'text',
// 2. React 속성
className: 'my-input-class',
// 3. styled-components 특수 속성
as: 'input',
// 4. Custom Prop (스타일에서 사용)
$isFocus: true,
})`
background: ${props => (props.$isFocus ? 'white' : 'gray')};
`;
9. 결론
- Typography 프리셋은 순수 styled-component + attrs 기반이 구조적으로 더 안정적
- 디자인 시스템 관점에서 선언적이고 확장성이 좋음
- 복잡한 조건 로직이 필요한 경우에만 함수형 컴포넌트 사용을 고려하는 것이 적절함
'Web Development > ETC' 카테고리의 다른 글
| 백엔드 데이터 요청 로직 개선 사례 공유 (0) | 2026.01.09 |
|---|---|
| [ETC] 모듈 번들러와 Vite, Webpack 비교 (1) | 2024.12.15 |
| [ETC] 어떤 기능을 개발하기 전 생각해볼 것 (4) | 2024.04.24 |
| [ETC] 정규식 (Regex) 이해하기 (2) | 2024.04.02 |
| [GTM, GA4] GTM, GA4 을 통해서 웹사이트 내의 고객 활동 추적하기 (0) | 2023.02.16 |