Notice
Recent Posts
Recent Comments
Link
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
관리 메뉴

차근차근

[React-Native] (4) 모바일 컴포넌트 본문

대학교/FE

[React-Native] (4) 모바일 컴포넌트

SWKo 2020. 3. 11. 00:13

0. HTML 엘리먼트와 네이티브 컴포넌트의 유사성

  • 리액트 네이티브에서는 HTML 엘리먼트를 사용하지 않고, 이와 매우 유사하면서 다양한 컴포넌트를 사용한다.
HTML 리액트 네이티브
div <View>
img <Image>
span, p <Text>
ul/ol, li <FlatList>, 자식 아이템
  • 이 엘리먼트들은 비록 서로를 대체할 수는 없지만 아주 비슷한 용도로 쓰인다.

1. <Text> 컴포넌트

  • 텍스트 렌더링은 매우 기본적인 기능이다.
  • HTML에서는 다양한 엘리먼트(<string>, <em> 등)로 텍스트를 표시할 수 있다.
  • 리액트 네이티브에서는 <Text> 컴포넌트만이 플레인 텍스트 노드를 자식으로 가질 수 있다.
  • 리액트 네이티브에서 <Text> 컴포넌트를 다룰 때는 <string>, <em>같은 하위 태그를 사용할 수 없으나 fontWeight, fontStyle 속성을 이용하여 비슷한 효과를 낼 수 있다.
  • 리액트 네이티브에서 스타일이 적용된 텍스트를 다룰 때는 웹 개발과는 다르게 접근해야 한다.
  • 스타일은 하위 노드에게 상속되지 않기에, 트리에 속한 모든 텍스트 노드에 적용되는 기본 폰트를 지정할 수 없다.
  • 리액트 네이티브 문서에도 이 문제를 스타일이 적용된 컴포넌트로 해결할 것을 권하고 있다.
  • 리액트 네이티브는 같은 스타일을 반복적으로 사용해야 할 경우 스타일의 상속이나 객체의 재사용이 아닌 스타일이 적용된 컴포넌트의 재사용을 더 권장하고 있다.
  • 별도의 컴포넌트로 만들 때는 시간이 많이 들기는 하지만 이 방법은 코드 분리가 명확히 되어 이 컴포넌트가 어디에서 사용되든 똑같은 결과물을 만들어 낸다.
  • 이는 앱 제작에 있어 스타일 코드를 관리하기 쉽게 해준다.

2. <Image> 컴포넌트

<Imgae> 컴포넌트의 기본적인 사용법은 간단하다. 그냥 source속성만 지정하면 된다.

  • <Image source={require("./puppies.png")/>
  • 앱에 에셋으로 포함한 이미지 대신에 웹에 있는 이미지를 불러와서 보여줄 수도 있다.
  • <Image source={{uri:"https://facebook.github.io/react/img/logo_og.png"}} style={{width:400, height:400}} />
  • 웹에 있는 이미지 소스를 이용할 경우 이미지 사이즈를 따로 지정해야 한다.
  • 이미지를 네트워크 주소로 지정하는 것은 이미지를 에셋으로 포함시켜 지정하는 것보다 약간의 이점이 있다.
    • 개발 기간에 프로토 타이핑할 때는 미리부터 모든 에셋을 꼼꼼히 import하는 것보다 이 방법을 사용하는 것이 더 쉽다.
    • 모바일 앱의 저장 용량을 줄여주어 사용자가 앱을 내려받을 때 모든 에셋을 한꺼번에 같이 내려받지 않아도 된다.
  • 기본 HTML과 CSS에서는 background-image속성을 이용하여 배경을 적용하지만 리액트 네이티브에서는 <Image>를 다음과 같이 컨테이너 컴포넌트로 사용한다.

<Image source={require("./puppies.png")}/>

        {/* 추가 내용 */}

</Image>

 

  • 스타일을 적용할 수 있을뿐만 아니라 렌더링되는지를 props로 지정할 수 있다.
  • 예를 들어 resizeMode는 contain, cover 혹은 stretch로 지정할 수 있다.

3. 터치와 제스처(Gestures) 다루기

  • 웹 기반 인터페이스는 마우스 형태의 컨트롤러를 위해 디자인되었다.
  • hover 상태 등을 이용하여 사용자에게 인터랙션 가능 여부를 표시하고 사용자 인터랙션에 반응하게 만든다.
  • 모바일은 터치 기반이다. 모바일 플랫폼상에서 인터랙션을 디자인할 때 알아야 하는 모바일 플랫폼만의 기준이 있다.
  • 리액트 네이티브는 터치에 반응하는 인터페이스를 만들 수 있도록 여러 API를 제공하고 있다.
  • <Button>
    • <Button> 컴포넌트는 쓸만한 컴포넌트이긴 하나 실제 앱을 만들다보면 상호작용이 가능한 컴포넌트를 만들어야 하기에 <TouchableHighlight>가 더 유용할 것이다.

  • <TouchableHighlight>
    • <TouchableHighlight> 는 뷰가 터치될 때 오버레이를 추가하여 사용자에게 시각적 피드백을 준다.
    • 이는 현재 화면인 모바일 웹사이트가 네이티브 앱이라 느껴지게 만드는 데 중요한 역할을 한다.
    • 버튼이나 웹의 링크가 되는 거의 모든 영역에 <TouchableHighlight>를 사용하게 될 것이다.
    • 기본적인 사용법은 사용자가 눌렀을 때 간단한 오버레이가 추가되길 원하는 컴포넌트를 <TouchableHighlight>로 감싸면 된다.
    • <TouchableHighlight>의 onPressIn, onPressOut, onLongPress와 같은 콜백을 지정하면 해당하는 이벤트를 다룰 수 있다.
    • <TouchableHighlight> 와 <TouchableOpacity>의 차이점은 아래와 같다.
    • <TouchableHighlight>는 누르면 어둡게 해주고 <TouchableOpacity>는 밝게 해준다.

누르지 않은 경우
누른 경우

  • PanResponder 클래스
    • <TouchableHighlight>는 컴포넌트이지만 PanResponder는 컴포넌트가 아니라 리액트 네이티브에서 제공하는 클래스이다.
    • PanResponder gestrue State 객체를 통해 현재 제스처의 속도, 누적 이동거리 등과 같은 원시 위치 데이터에 접근할 수 있다.
    • 리액트 컴포넌트에서 PanResponder를 사용하기 위해서는 PanResponder객체를 생성하고 컴포넌트의 렌더 함수에 결합해야 한다.
    • PanResponder를 생성하려면 PanResponder이벤트를 위한 특정 핸들러를 지정해야 한다.
    • 여섯가지 함수를 통해 터치 이벤트의 전체 라이프사이클에 접근할 수 있다.
    • onStartShouldSetPanResponder, onMoveShouldSetPanResponder => 주어진 터치 이벤트에 반응할지를 결정
    • onPanResponderGrant => 터치 이벤트가 발생할 때 실행
    • onPanResponderMove => 터치 이벤트가 진행중일 때 터치 정보 확인 가능
    • onPanResponderRelease, onPanResponderTerminate => 터치 이벤트가 끝날 때 실행
  • 터치를 다루는 법 선택하기
    • 사용자에게 버튼이나 다른 엘리먼트가 '탭이 가능하다는 것'을 알려주는 기본적인 피드백을 주고 싶을 때는 <TouchableHighlight> 컴포넌트를 사용하자.
    • 자체적인 터치 인터페이스를 구현하고 싶을 때는 PanResponder를 사용하자.

4. 리스트 관련 컴포넌트

  • 리스트는 모바일 앱 개발에 있어 매우 핵심적인 인터페이스이다.
  • 리스트를 한 문장으로 표현하자면 리스트는 여러 자식 뷰를 가질 수 있는, 스크롤되는 컨테이너이다.
  • 리액트 네이티브에는 편리한 API를 제공하는 두 가지 리스트 컴포넌트가 있다.
  • 하나는 <FlatList> 컴포넌트로 이는 내용이 변하는 긴 스크롤 리스트이지만 데이터 구조가 비슷한 경우를 위해 디자인되었다. 이는 여러가지 측면에서 성능이 최적화되어 있다.
  • 다른 하나는 <SectionList> 컴포넌트로 이는 데이터를 섹션으로 구분해서 보여줘야 하는 경우를 위해 디자인되었다.
  • <FlatList>나 <SectionList>로 웬만한 리스트를 대부분 만들 수 있지만 리스트에 내부적으로 어떤 기능을 넣는다거나 독특하게 리스트를 다뤄야 한다면 <VirtualizedList>를 살펴보자.
  • 뉴욕타임즈 베스트셀러 목록과 각 책에 대한 상세 정보를 보여주는 앱을 <FlatList>를 사용하는 버전과 <SectionList>를 사용하는 버전으로 구분하여 만들어보자.
  • <FlatList> 버전
    • 기본 <FlatList> 컴포넌트는 props로 data와 renderItem을 반드시 지정해야 한다.
    • data는 이름에서 알 수 있듯이 <FlatList>에서 렌더링할 데이터를 의미한다.
    • 이는 배열 타입으로 각 엘리먼트는 고유의 각 key값을 가지고 있어야 한다.
    • renderItem 함수는 data배열에 속한 하나의 엘리먼트 데이터를 바탕으로, 해당하는 컴포넌트를 리턴하도록 구현한다.

<FlatList> 기반의 SimpleList 컴포넌트 코드
<FlatList> 기반의 SimpleList 컴포넌트 결과화면


5. <FlatList>

  • <FlatList> 내용 갱신하기
    • 뉴욕타임스 API를 이용하여 베스트셀러 목록을 보여주는 베스트셀러 앱을 만들어보자.
    • 먼저, 렌더링 할 컴포넌트인 BookItem.js 파일을 작성해보자. 다음과 같다.

  • <BookItem> 컴포넌트를 사용하기 위해서는 _renderItem 함수를 수정해야 한다. <BookItem>의 props에 coverURL, title과 author를 지정해야 한다.
  • 또한 <FlatList>에 지정하는 data 배열의 각 항목에는 반드시 고유의 값을 갖는 key속성이 지정되어야 한다.
    • 배열의 각 항목에 key속성을 넣어주는 헬퍼 메서드 _addKeysToBooks 를 추가한다.
  • MocBookList.js라는 파일을 만들고 작성해보겠다.

  • App.js에서 다음과 같이 작성한다.

  • 결과화면은 다음과 같다.

  • 위에서는 모의 데이터를 가지고 하였다. 이제 실제 데이터를 연결해보겠다.

 

  • 먼저 API에서 데이터를 가져오기 위해 NYT.js 파일을 만들고 다음과 같이 코드를 작성한다.

  • 그 후 뉴욕타임스 API를 호출하는 _refreshData 메서드를 추가한다.

  • 마지막으로 비어 있는 배열을 state의 기본값으로 지정하고 _refreshData함수를 componentDidMount에서 호출한다.
  • BookList.js 의 코드는 다음과 같다.

  • 결과적으로 다음과 같은 화면이 나온다.(사이트url이 바뀌어서 사진은 기존 사진으로 대체하였다.)

  • 이와 같이 <FlatList> 컴포넌트는 데이터 목록을 짜임새 있게 보여줘야 할 때 손쉽게 적용할 수 있다.
  • 게다가 스크롤과 터치 인터랙션을 다루는 것도 가능할 뿐만 아니라 렌더링 스피드와 메모리 사용량을 줄이기 위해 성능 최적화 기술이 많이 적용되어 있다.

6. <SectionList>

  • <SectionList>는 대부분 비슷한 형태의 아이템을 가지고 있는 목록을 섹션 헤더와 함께 표시하기 위해 만들어진 컴포넌트이다.
  • 예를들어 여러 분야의 베스트셀러 목록을 보여줄 때 각 분야마다 헤더를 표시하고자 한다면 <SectionList>를 사용하는 것이 좋은 선택이다.
  • <SectionList>에는 sections, renderItem 과 renderSectionHeader를 지정해야 한다.
  • sections는 섹션 데이터를 가지고 있는 객체의 배열이다.
  • 각 섹션 객체는 title과 data속성을 가지고 있어야 한다.
  • data는 <FlatList>의 data와 비슷하다. 즉, 항목마다 고유의 key를 가지고 있는 배열이다.

7. 네비게이션

  • 모바일 앱 개발 분야에서 내비게이션이란 일반적으로 사용자로 하여금 한 화면에서 다른 화면으로 이동시키는 코드를 말한다.
  • 네비게이션을 구현하기 위해서 React Native가 기본으로 제공하는 <Navigator>와 <NavigationIOS> 뿐만 아니라 커뮤니티가 만든 (react-navigation 라이브러리가 제공하는) <StackNavigator>가 많이 사용된다.
  • 모바일 앱에서 화면 간 이동을 위해서는 네비게이션 로직이 필요하다.
  • 또한 사용자가 특정 URL을 통해 앱의 특정 화면으로 이동할 수 있는 '딥 링킹(deep linking)' 구현도 필요하다.
  • 10장에서 다시 알아보자.

8. 짜임새를 위한 컴포넌트

  • 짜임새를 위한 컴포넌트는 <TabBarIOS>와 <SegmentedControlIOS>나 <DrawerLayoutAndroid>, <ToolbarAndroid> 등 유용한 컴포넌트들이 상당히 많다.
  • 한 가지 눈여겨볼만한 사항은 앞서 언급한 모든 컴포넌트의 이름에는 특정 플랫폼을 뜻하는 접미사가 있다는 사실이다.
  • 왜냐하면 이 컴포넌트들은 플랫폼 특유의 UI엘리먼트를 렌더링하기 위해 네이티브 API를 사용하고 있기 때문이다.
  • 이러한 컴포넌트들은 앱을 여러 화면으로 구성할 때 매우 유용하다.
  • 예를 들어 <TabBarIOS>와 <DrawerLayoutAndroid>를 이용하면 여러 모드나 기능 간의 전환을 쉽게 할 수 있다.
  • <SegmentedControlIOS>와 <ToolbarAndroid>는 좀 더 세부적인 컨트롤에 적합하다.
  • 이런 컴포넌트를 올바르게 사용하기 위해서 플랫폼별 디자인 가이드를 참고할 필요가 있다.
  • 크로스 플랫폼 앱에서 플랫폼에 특화된 컴포넌트를 다루는 방법은 7장에서 보겠다.

'대학교 > FE' 카테고리의 다른 글

[React-Native] (6) 플랫폼 API  (0) 2020.03.15
[React-Native] (5) 스타일  (0) 2020.03.14
[React-Native] (3) 애플리케이션 만들기  (0) 2020.03.10
[Redux] Redux를 이용한 CRUD  (0) 2020.03.08
[Redux] 시간여행과 로깅  (0) 2020.03.08
Comments