반응형
이번 Template Component 는 기존 앞의 두 개 포스트와는 다른 좀 더 복잡하지만 효용성이 높은 Compound Component Design 패턴을 이용하여 만들어 보겠습니다.
우선 Compound Component Design에 대해 간단히 설명하고 사례를 들어보면 이해가 좀 더 쉽게 될 것 같습니다.
1. Compound Component Design
- 일반 컴포넌트와 다른 점은 다음과 같습니다.
- 일반 컴포넌트
: 단일 컴포넌트로 구성되며, props를 통해 데이터나 함수를 전달 받음
: 로직과 UI가 하나의 컴포넌트에 집중 - 컴파운드 컴포넌트
: 여러 개의 관련 컴포넌트를 하나의 부모컴포넌트에 그룹화하여 구성함
: 부모 컴포넌트가 전체 로직과 상태를 관리하고, 자식 컴포넌트들과 공유
: 로직은 부모 컴포넌트에, UI는 자식 컴포넌트에 분리
: 더 유연한 구조로 사용자가 필요한 서브컴포넌트만 선택적으로 사용 가능
: 구조와 스타일을 더 쉽게 커스터마이징 가능
: 관련 컴포넌트들의 로직을 한 곳에 관리하므로 유지보수가 용이
- 일반 컴포넌트
- 컴파운드 컴포넌트의 단점?
- 컴포넌트의 구조가 복잡해짐
- Context API를 사용하지 않으면 자식 컴포넌트 간 데이터 공유에 제약이 있을 수 있음
- 컴포넌트 간 강한 결합이 생길 수 있어 분리가 어려울 수 있음
2. Header Compoud Component 만들기
앱의 헤더에는 화면 타이틀, 백 버튼, 닫기 버튼 등 다양한 컴포넌트의 조합이 필요하여 컴파운트 컴포넌트로 구현해 보겠습니다.
- 구성
- src (소스) > components > Header 폴더 생성하고 하위에 다음의 파일 생성
- 부모 컴포넌트 : Header
- 서브 컴포넌트: HeaderButton, HeaderGroup, HeaderTitle
- HeaderButton Component 만들기
- 기본 컴포넌트로 만든 Button, Icon 사용
- props로 버튼 선택시 동작 함수와 표출할 아이콘 이름, 크기, 색상을 넘겨줌
import React, { Component } from 'react';
import Button from '../Button';
import Icon from '../Icons';
export default class HeaderIcon extends Component {
render() {
return (
<Button onPress={this.props.onPress}>
<Icon name={this.props.iconName} size={28} color='black' />
</Button>
)
}
}
- HeaderTitle Component 만들기
- 헤더에 표시할 화면 제목으로 Typography 컴포넌트 활용
- props로 타이틀 텍스트와 폰트사이즈를 넘겨줌
import React, { Component } from 'react';
import Typography from '../Typography';
export default class HeaderTitle extends Component {
render() {
return (
<Typography fontSize={18}>{this.props.title}</Typography>
)
}
}
- HeaderGroup Component 만들기
- Button과 Title 컴포넌트를 그룹으로 묶기 위한 컴포넌트로 두 컴포넌트의 배열 등 스타일 지정
import React, { Component } from 'react';
import { View } from 'react-native';
export default class HeaderGroup extends Component {
render() {
return (
<View style={{flexDirection:'row', alignItems:'center'}}>
{this.props.children}
</View>
)
}
}
- Header Component 만들기
- 부모 컴포넌트로 전체 화면에 배치와 필요한 props값을 서브컴포넌트에 전달하는 역할
- 디바이스 특성에 따른 노치, 상태바, 홈인디케이터 등 으로 인해 방해받지 않고 화면표출을 정상적으로 하기 위해 Safe Area Insets Context 라이브러리를 설치하고 사용
- npm install react-native-safe-area-context
- class 형식의 컴포넌트에는 SafeAreaInsetsContext 사용
- 함수형 컴포넌트에는 SafeAreaView 사용
- insets 으로 안전영역에 해당되는 padding값을 넘겨줌
- 컴포넌트 하단에 서브컴포넌트 사용에 대해 정의해줌
import React, { Component } from 'react';
import { SafeAreaInsetsContext } from 'react-native-safe-area-context';
import { Dimensions, View } from 'react-native';
import Spacer from '../Spacer';
import HeaderTitle from './HeaderTitle';
import HeaderIcon from './HeaderButton';
import HeaderGroup from './HeaderGroup';
const { width } = Dimensions.get('window');
export default class Header extends Component {
render() {
return (
<SafeAreaInsetsContext.Consumer>
{insets => (
<View style={{paddingTop:insets.top}}>
<View style={{
width:width,
flexDirection:'row',
height:56,
borderBottomColor:'gray',
borderBottomWidth:1,
alignItems:'center',
}}>
<Spacer horizontal={true} space={12} />
<View style={{flex:1, flexDirection:'row', justifyContent:'space-between'}}>
{this.props.children}
</View>
<Spacer horizontal={true} space={12} />
</View>
</View>
)}
</SafeAreaInsetsContext.Consumer>
)
}
}
Header.Title = HeaderTitle;
Header.Icon = HeaderIcon;
Header.Group = HeaderGroup;
- App.js 에 Header Component 적용하기
- 컴포넌트 명칭은 Header의 서브 컴포넌트로 표현
- Header.Group, Header.Icon, Header.Title
- 서브 컴포넌트로 props 전달
- 헤더 타이틀 : HEADER
- 아이콘 : arrow-back , close
- 컴포넌트 명칭은 Header의 서브 컴포넌트로 표현
import { View } from 'react-native';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import Header from './src/components/Header/Header';
export default function App() {
return (
<SafeAreaProvider>
<View style={{ flex: 1 }}>
<Header>
<Header.Group>
<Header.Icon iconName='arrow-back'></Header.Icon>
<Header.Title title='HEADER'></Header.Title>
</Header.Group>
<Header.Icon iconName='close'></Header.Icon>
</Header>
</View>
</SafeAreaProvider>
);
}
지금까지 다양한 기본컴포넌트와 좀 더 복잡한 컴파운드 컴포넌트에 대해 다뤄 보았습니다.
프로젝트에 맞게 일부 수정하여 사용하면 다양한 앱을 만들 때 좀 더 쉽고 일관성 있게 개발할 수 있을 것 같습니다.
반응형
'리액트(React)' 카테고리의 다른 글
React Native - 외부글꼴 사용 및 전역 색상관리하기 (0) | 2024.11.16 |
---|---|
Expo Splash Screen 만들기 (0) | 2024.11.15 |
React Native - 기본 Template Component 만들기(2) (1) | 2024.11.12 |
[React] 유용한 Prop-Types 활용하기 (4) | 2024.11.12 |
React Native - 기본 Template Component 만들기(1) (1) | 2024.11.11 |