React
+ TypeScript
+ CSS Module
확장성 or 재사용성이 높은 컴포넌트를 만들기 위해서는 해당 컴포넌트가 도메인에 얽혀있으면 안된다.
예를들면, 색깔이 다른 버튼 컴포넌트를 이름을 바꾸어 여러개 만드는 경우가 있다. 버튼 하나를 만들어 color
라는 props
를 내려주는것이 확장성이 높다.
import { ReactNode } from 'react';
import styles from '../styles/Button.module.css';
type Size = 'sm' | 'lg';
type Color = 'white' | 'blue';
interface ButtonProps {
type?: 'submit' | undefined;
color: Color;
size: Size;
className?: string;
onClick?: () => void;
children: ReactNode;
}
function Button({
type,
color,
size,
className,
onClick,
children,
}: ButtonProps) {
let combinedClassName = `${styles['button']}`;
switch (color) {
case 'white': {
combinedClassName += ` ${styles['white']}`;
break;
}
case 'blue': {
combinedClassName += ` ${styles['blue']}`;
break;
}
}
switch (size) {
case 'sm': {
combinedClassName += ` ${styles['sm']}`;
break;
}
case 'lg': {
combinedClassName += ` ${styles['lg']}`;
}
}
return (
<button className={combinedClassName} onClick={onClick}>
{children}
</button>
);
}
export default Button;
기본 버튼을 만들어준다.
type Size = 'sm' | 'lg';
type Color = 'white' | 'blue';
우리는 버튼의 크기와 버튼의 색상을 props로 내려 재사용성을 높일 것이다.
let combinedClassName = `${styles['button']}`;
switch (color) {
case 'white': {
combinedClassName += ` ${styles['white']}`;
break;
}
case 'blue': {
combinedClassName += ` ${styles['blue']}`;
break;
}
}
switch (size) {
case 'sm': {
combinedClassName += ` ${styles['sm']}`;
break;
}
case 'lg': {
combinedClassName += ` ${styles['lg']}`;
}
}
본인은 CSS Module을 사용중이므로, combinedClassName의 기본 className으로 공통 스타일인 button을 적용한다.
그 후 switch case를 통해 버튼의 색상과 크기 className을 지정해준다.
import styles from '../styles/Header.module.css';
import Button from './Button';
import CalendarIcon from './icons/CalendarIcon';
import SearchIcon from './icons/SearchIcon';
function Header() {
return (
<header className={styles['container']}>
<div className={styles['buttons-container']}>
<Button color='white' size='sm'>테스트1</Button>
<Button color='white' size='lg'>테스트2</Button>
<Button color='blue' size='sm'>테스트3</Button>
</div>
</header>
);
}
export default Header;
버튼을 사용하는 부분에서 Button
컴포넌트의 props
만 바꾸어 사용하면 된다.