코드를 작성하다보면 중복된 코드가 생겨납니다.
중복된 코드를 반복적으로 작성하게된다면 코드 양이 많아지게되고, 코드 양이 많아질수록 유지보수 난이도는 증가합니다.
한 번 작성된 코드를 재사용
할 수 있도록 Component로 만들어주게 된다면 중복된 코드를 작성하지 않아도 됩니다.
하지만 너무 잦은 컴포넌트화는 예상하지 못한 변경점이 생기면서 버그로 이어질 수 있습니다.
작은단위부터 큰 단위까지의 컴포넌트를 조합해 만들어가는 것 입니다.
ATOMS
->MOLECULES
->ORGANISMS
->TEMPLATES
->PAGES
보여주는 일에만 집중하는 Component 입니다.
state
를 가지고 있지 않고, props
를 통해 어떻게 보여줄지에 대해서만 집중한 Component 입니다.
가장 작은 단위의 ATOMS
Component를 만들 때에는 state
가 필요한 경우는 드물기 때문에 Dumb Component인 경우가 많습니다.
상태를 가지로 스스로 변하는 Component 입니다.
스스로 state
를 가지고 있고, 어떠한 계산을 통해서 변하는 것 까지 가능한 Component 입니다.
가장 작은 단위는 우선적으로 Component 로 만들어 재사용하고,
Molcule
이상의 단계들 중에서 3회이상 반복되면 Component 로 만들어주는 것이 좋습니다.
> npx create-expo-app example_component
git repository 에도 연결해주었습니다.
앱을 구성하는 가장 작은 단위인 Typography인 Text
, Button
, Image
를 Component 로 만들어주려 합니다.
이런 작은 단위의 구성요소들은 앱을 만들기 시작할 때 만들어두지 않으면, 추후에는 Component화가 어렵고, 화면마다 다른 Component를 사용하게 되는 경우가 많습니다.
src
폴더를 만들고 그 안에 components
폴더를 만들고, 그 안에 Typography.js 파일을 생성해주었습니다.
fontSize
와 color
를 조절할 수 있 는 간단한 컴포넌트입니다.
App.js에서 사용해주었습니다.
RNText
요소 안에 입력한 문구가 잘 표시됩니다.
Typography 컴포넌트에서 fontSize
, color
를 prop으로 받을 수 있게 해두었으니, 원하는 색상과 크기로 변경하기 위해 prop을 넘겨주었습니다.
Text
의 경우에는 중첩하여 사용할 수도 있습니다.
RNText
를 중첩하여 사용하여, 텍스트
부분의 색상만 다르게 해주었습니다.
fontSize
prop에 숫자가 아닌 문자열이나 다른 값이 들어가게 된다면, 버전에 따라서 오류가 나거나, 아에 없는 값인것 처럼 적용이 안된 채로 동작하는 경우가 있습니다.
prop-types
를 사용해서 prop에 어떤 단위가 들어오는지 검증해보려 합니다.
> npm install prop-types
우선 라이브러리를 install 해주었습니다.
Typography 의 propTypes 를 세팅해주었습니다.
App.js 에서 fontSize
의 prop에 문자열을 넘겨주었습니다.
fontSize
의 type이 number
여야하는데 string
이라고 Warring을 띄워줍니다.
해당 기능은 JavaScript에서 type Check를 할 수 있다는 점을 알기 위해 사용해 보았습니다.
src
폴더의 components
폴더 안에 LocalImage.js 파일을 생성해주었습니다.
이미지의 source
와 style
을 props으로 받고, style
중에서 width 와 height를 직관적으로 받아주었습니다.
App.js에서 사용해주었습니다.
expo
에서 기본으로 제공해주는 assets폴더 안의 이미지 경로를 localAsset
으로 주었고, width
와 heigh
를 넘겨주었습니다.
이미지가 표시된 모습입니다.
src
폴더의 components
폴더 안에 RemoteImage.js 파일을 만들어주었습니다.
uri
와 style
을 받아줍니다.
App.js에서 이미지 주소와 크기를 넣어주었습니다.
이미지가 잘 출력된 모습입니다.
src
폴더의 components
폴더 안에 Icons.js 파일을 만들어주었습니다.
name
, size
, color
props을 받아옵니다.
App.js에서 사용해주었습니다.
노란색 home
아이콘이 나타난 모습입니다.
아이콘의 종류나 name
등의 정보는 해당 사이트에서 확인할 수 있습니다.
src
폴더의 components
폴더 안에 Badge.js 파일을 만들어주었습니다.
View
로 감싸주고 style을 지정해주었습니다.
좌측상단에 고정되도록 해주었습니다.
App.js에서 사용해주었습니다.
Typography와 Icon에 Badge
를 적용해보았습니다.
Text
와 Icon
우측위에 Badge
가 표시된 모습입니다.
src
폴더의 components
폴더 안에 Button.js 파일을 만들어주었습니다.
눌렀을때 동작할 함수인 onPress
와 터치영역인 htiSlop
을 props으로 받아줍니다.
App.js에서 사용해줍니다.
버튼을 눌렀을 때 로고가 잘 찍히는 모습입니다.
Icon으로도 버튼을 만들어주었습니다.
![](https://velog.velcdn.com/images/bi-sz/pos![](https://velog.velcdn.com/images/bi-sz/post/8e0e78de-f55b-4c93-ae61-eceda5a20dc1/image.png)
t/afb6614f-0fef-4bd6-b5a4-c72e6ae0faea/image.png)
분홍색 아이콘이 보이고, 이 아이콘은 버튼으로 동작합니다.
눌렀을 때 로고가 잘 찍히는 모습입니다.
구분선입니다.
src
폴더의 components
폴더 안에 Divider.js 파일을 만들어주었습니다.
View
로 감싸주고 style을 지정해주었습니다.
App.js에서 사용해주었습니다.
구분선이 잘 표시된 모습입니다.
여백을 주는 컴포넌트입니다.
src
폴더의 components
폴더 안에 Spacer.js 파일을 만들어주었습니다.
App.js에서 중간중간 추가해주었습니다.
Spacer 컴포넌트를 추가한 부분에 공간이 생긴 모습입니다.
src
폴더의 components
폴더 안에 TabIcon.js 파일을 만들어주었습니다.
이전에 만들어두었던 ATOM Component인 Badge
와 Icon
을 사용해주었습니다.
App.js에서 사용해주었습니다.
익숙한 아이콘이네요. 해당 어플의 알람 여부 혹은 개수를 알려주던 아이콘의 모습입니다.
TabIcon 컴포넌트에서 조건을 추가하였습니다.
visibleBadge
가 있으면 Badge
를 보여주고, 아니면 Icon
만 Return되도록 수정해주었습니다.
App.js에서 두 가지 경우 모두 사용해보겠습니다.
visibleBadge
의 여부에 따라 Badge
가 있는 Icon
과, Badge
가 없는 Icon
이 보여집니다.
Compound Component Pattern
Header
의 경우는 요구사항에 따라 변경되는 경우가 많기 때문에 유연하게 대응해야합니다.
Component
자체에 SubComponent API를 제공해서 SubComponent가 어떤 형태인지 제공해줍니다.일반적으로는
Component
는props
를 통해서 어떻게 보여줄지를 작성하지만, Compound Component Pattern 을 적용하게되면 새로운Component
가 추가됐을때 기존 코드를 보고 옵션에 대한 분기처리를 할 필요가 없어집니다.
SafeAreaContext
상단바, 혹은 하단바 영역을 제외한 영역에 화면이 그려지도록 도와주는 라이브러리입니다.
npm install react-native-safe-area-context
라이브러리를 install 해주었습니다.
src
폴더의 components
폴더 안에 HeaderWithoutCompound.js 파일을 생성해주었습니다.
return으로 SafeAreaContext.Cunsumer
를 사용해주었고, insets
이라는 것을 이용해줍니다.
RN에서 제공해주는 Dimensions
를 이용해주었습니다.
width는 Dimesions
, height는 일반적으로는 56
정도로 사용합니다.
현업에서는 height는 보통 지정해준다고 합니다.
title
이 들어갈 Typography 부분, leftIcon
, rightIcon
과 Spacer 로 여백을 주었습니다!
App.js 에서 HeaderWithoutCompound를 사용해주었고, title
을 작성해주었습니다.
Component를 이래서 사용하나봅니다..
그 동안은 Header
부분을 App.js에 대충 작성했던거 같은데 차이점이 확 드러나네요.
이렇게 작성해둔
Header
에 대해 수정사항이 생긴다면title
혹은Icon
리소스를 변경해야한다면Header
에서Button
의 추가,제거등의 분기가 이루어지려면 자체 스택을 고쳐야합니다.
Header
의 수정으로 인하여 영향받는 모든 화면을 재검수해야합니다.수정으로 인한 오류를 모두 잡아내지 못한다면 버그가 되게됩니다. 모든 화면에서 헤더가 잘 표시되는지 테스트해야하는 상황이 생깁니다.
이런상황을 대비해서 Compound Component Pattern을 통해 관리할 수 있습니다.
Header
src
폴더의 components
폴더 안에 Header
폴더를 하나 더 만들었고 그 안에 Header.js 파일을 추가해주었습니다.
Header 에 적용할 Component들을 구분하기 위해 따로 폴더를 추가해주었습니다.
기본적인 Header의 root
가 될 코드를 작성해주었습니다.
처음 작성할땐 어지러웠는데 한 번 더 보니까 이젠 그래도 구조를 알겠네요.
HeaderTitle
Header
폴더 안에 HeaderTitle.js 컴포넌트를 만들어주었습니다.
title
이 들어갈 Typograghy 만 return
해줍니다!
HeaderButton
Header
폴더 안에 HeaderButton.js 컴포넌트를 만들어주었습니다.
마찬가지로 Icon
Button
만 return 해줍니다.
root
인 Header 컴포넌트에 넣어줍니다!
App.js 에서 기존 HeaderWithoutCompound 대신 새로 만든 Header 컴포넌트를 적용해주었습니다.
Header
의 Header.Icon, Header.Title로 Icon
과 Title
의 prop을 넘겨줍니다.
Header가 나타났는데 space-between
을 주어서 그런 것 같습니다. 이것을 해치지 않기 위해서 컴포넌트를 하나 더 추가하겠습니다.
HeaderGroup
Header
폴더 안에 HeaderGroup.js 컴포넌트를 만들어주었습니다.
Header 컴포넌트에도 추가해주었습니다.
App.js에서 HeaderGroup
으로 묶어주었습니다.
close Icon
도 추가해주었습니다.
Header가 완성된 모습입니다.
Compound Component Pattern 적용한
Header
를 보니 직관성이 좋아Header
가 어떻게 작성되어있는지 한 눈에 들어옵니다.전체 코드가 길어진 감이 있고 전체 파일의 길이가 길어졌지만, 각각의 Component로 나눠서 구현을 해 두었기 때문에 어떠한 요구사항이 들어왔을 때 수정이 용이하며, 버그의 위험도도 낮아집니다.
이번 게시글에서 작성한 많고 많은 Component들을 작성하면서 솔직히 지겨웠는데요,,
이전에 만든 프로젝트를 진행하면서도 이미 알고있던 내용들 반복하는 것 같아서 타자연습을 엄청 열심히한 느낌이고 영타가 빨라진 장점만 느끼고 있었습니다.
Header
Compononet를 작성하면서 미리 만들어 둔 Component들을 사용하니까 훨씬 빠르고 아 이래서 ATOM
Component 를 프로젝트를 시작하면서 미리 만들어두는구나를 느꼈습니다.
이번 게시글에서 작성한 컴포넌트들은 이후 다른 프로젝트를 진행하면서도 유용하게 사용할 것 같습니다.
옵션을 추가하거나 상태를 추가하여 언제든지 확장할 수 있겠네요.