1. 개요
기존의 아이콘 컴포넌트는 Ionicons 만 사용 가능하도록 설계되었습니다.
export interface IconProps {
name: keyof typeof Ionicons.glyphMap;
color?: string;
size?: number;
style?: StyleProp<ViewStyle>;
}
const Icon = ({name, color, size = 24, style}: IconProps,) => {
const fontSize = 24;
return (
<>
{name && (
<Ionicons name={name} size={size || fontSize} color={color} style={style}/>
)}
</>
)
}
export default Icon
Java
복사
그래서 다음과 같이 Icon을 사용할 때, Ionicons 에 등록되지 않은 이름이라면 실행되지 않았습니다.
<Icon name={'left'} size={18} color={'#FFFFFF'} /> // 'left' 에서 에러 발생
Java
복사
이를 확장성 있는 설계로 리팩토링 해보겠습니다.
2. 리팩토링
export type IconLibrary = 'Ionicons' | 'MaterialIcons' | 'FontAwesome';
export interface IconProps {
library: IconLibrary;
name: string;
color?: string;
size?: number;
style?: StyleProp<ViewStyle>;
}
const Icon = ({ library, name, color, size = 24, style }: IconProps) => {
const renderIcon = () => {
switch (library) {
case 'Ionicons':
return <Ionicons name={name as keyof typeof Ionicons.glyphMap} size={size} color={color} style={style} />;
case 'MaterialIcons':
return <MaterialIcons name={name as keyof typeof MaterialIcons.glyphMap} size={size} color={color} style={style} />;
case 'FontAwesome':
return <FontAwesome name={name as keyof typeof FontAwesome.glyphMap} size={size} color={color} style={style} />;
default:
return null;
}
};
return <>{renderIcon()}</>;
};
export default Icon;
Java
복사
속성들을 조금 더 자세히 알아보겠습니다.
name={name as keyof typeof Ionicons.glyphMap}
glyphMap은 아이콘 이름과 실제 글리프 코드 사이의 맵을 의미합니다. 즉, 각 아이콘 라이브러리에는 여러 아이콘들이 있고, 아이콘의 이름을 텍스트로 주면 내부적으로 그 아이콘에 해당하는 글리프 코드로 변환하여 아이콘을 렌더링합니다.
StyleProp<ViewStyle>
StyleProp은 React Native에서 스타일을 적용할 때 사용하는 타입입니다. React Native에서 스타일은 기본적으로 JavaScript 객체 형태로 표현되지만, 다양한 형태의 스타일을 허용하기 위해 타입 정의가 좀 더 복잡합니다.
ViewStyle은 React Native의 View 컴포넌트에 적용 가능한 스타일 속성을 정의한 타입입니다. 이것은 width, height, margin, padding과 같은 속성들을 포함합니다.