React Native
RN은 Android와 IOS의 네이티브 앱을 React를 이용하여 개발할 수 있는 도구이다.
놀랍게도 아직 메이저 버전 넘버가 0이다.
React Native Team Principle
Native Experience
RN 팀의 최우선 가치는 사람들의 각 플랫폼에 대한 기대치를 충족시키는 것이다. (즉, RN을 써도 네이티브를 쓴 것과 같은 효과와 성능을 내게끔 하는 것.) 이것이 RN이 플랫폼 프리미티브로 렌더링 하는 이유이다. 따라서 플랫폼 간 일관성보다 네이티브 룩앤필(look-and-feel)을 중요시한다.
룩앤필을 맞추기 위해 성능도 맞춰야 한다. 이를 위해 페이스북에서는 Hermes라는, RN를 위한 안드로이드용 JS엔진을 개발했다.
Massive Scale
페이스북 모바일 앱의 수많은 화면은 RN으로 개발되었으며, 수많은 기기에서 실행된다. (모두 RN으로 개발한 건 아닌듯.) 페이스북은 플랫폼뿐만 아니라, 오래된 기기까지 호환 가능하도록 성능 향상에 힘을 쏟고 있다. 이러한 초점은 Hermes, Fabric, TurboModules와 같은 아키텍쳐 프로젝트에 개선점을 제공한다.
RN 팀은 RN이 거대한 규모로 확장할 수 있다는 것을 입증했으며, 개발자들을 위해 네이티브 스크린을 RN 스크린으로 어돕팅 및 마이그레이션 할 수 있도록 지원을 할 예정이다. (굳이 그 기능을 사용하는 개발자가 있을까..)
Developer Velocity
실행중인 앱의 코드의 변화를 수초 이내로 확인할 수 있다. (핫 리로딩) 개발 중 즉각적인 피드백을 통해, 작은 변경이 있을 때 마다 코딩 세션을 중단할 필요가 없을 때, 다양한 아이디어를 실험하거나 새로운 기능을 추가하는 게 더 쉽다. RN은 이러한 DX(Developer Experience) 품질을 유지하려고 노력한다.
Every Platform
RN의 출시 모토는 “Learn once, write anywhere”이다. 개발자는 OS나 기기에 한정되지 않고 최대한 많은 사용자에게 닿을 수 있어야 한다.
RN은 mobile, desktop, TV, game console 등 다양한 기기를 타겟으로 하고 있다. RN은 개발자들이 낮은 수준의 공통분모를 구축하도록 요구되는 대신, 각 플랫폼에서의 풍부한 경험을 제공하고자 한다. 이를 위해 각 플랫폼에서의 독특한 기능들을 지원하는 것을 중시한다.
이를 위해 RN의 새로운 코어 아키텍쳐를 C++로 개발하기로 결심했다. 또한 MicroSoft 같은 플랫폼 관리자를 겨냥한 공용 인터페이스도 개선중이다. 어떤 플랫폼이든 RN을 지원을 할 수 있도록 노력중이다.
Declarative UI
RN 팀은 모든 플랫폼에 동일한 UI를 제공할 수 없다고 믿는다. 대신, 동일한 선언적 프로그래밍 모델을 통해 각 플랫폼만의 독특한 능력을 드러내기로 했다. RN의 선언적 프로그래밍 모델은 React다.
RN팀은 명령적으로 관리되는 뷰보다 선언적인 컴포넌트들의 조합으로 화면을 표현하는 것을 더 선호한다.
특징
RN 공식 홈페이지의 메인페이지에 있는 특징들. RN을 이용해 네이티브 렌더링을 지원하는 것을 고려하면, 어댑터 패턴 느낌이 팍팍 난다.
JS로 작성, native code로 렌더
작성은 React와 유사하지만, 렌더링 시에는 네이티브 플랫폼 API를 사용하여 네이티브 플랫픔 UI로 렌더링한다. (애니메이션 관련 옵션 중에, 성능상의 이유로 애니메이션 관련 태스크를 네이티브에게 위임하는 옵션이 있다.)
따라서 하나의 코드베이스로 두가지 플랫폼용 코드를 관리할 수 있다.
네이티브 UI/UX
RN은 네이티브와 UI를 위한 최고의 라이브러리인 React를 결합했다. 진정한 네이티브 앱을 만들수 있고 UX를 해치지 않는다. (고 주장한다.) 이를 위해 플랫폼 UI에 직접적으로 매핑되는 View
, Text
와 같은 공용 코어 컴포넌트들을 제공한다.
심리스 크로스 플랫폼
RN의 코어 컴포넌트는 네이티브 코드를 래핑하며 네이티브 API와 통신한다. 이로 인해 네이티브 앱 개발이 가능해지며, 개발속도가 더 빨라진다.
핫 리로딩
기존의 웹 개발과 유사하게, 핫 리로딩을 지원해서 빠르게 변화를 확인할 수 있다.
페이스북의 지원, 커뮤니티 주도
거대 기업인 페이스북의 지원을 받고 있어, 프로젝트의 운영이 중단될 염려가 적다.
그리고 커뮤니티의 주도로 운영되므로 오픈소스 정신을 지킨다는 것을 알 수 있다. 특히, 일부 공용 컴포넌트는 아얘 커뮤니티 그룹(react-native-community)의 패키지를 사용하도록 권장하고 있다.
장점
크로스 플랫폼
RN으로 Android와 IOS용으로 동시에 개발이 가능하다.
높은 생산성
React와 JS에 친숙하다면 러닝커브가 낮다. 확실히 React와 비슷한 코딩 컨벤션을 가지고 있기 때문인 듯.
Expo라는 툴 덕분에 Android Studio와 XCode없이도 에뮬레이팅이 가능하다는데, 대부분의 반응들을 보면 Expo는 확장 및 커스터마이징의 한계가 뚜렷하다는 평이 많다. 나는 회사에서 CRNA(create-react-native-app)을 사용했음.
실시간 배포
아직 배포를 해보지 않아서 잘 모르지만, 앱 심사 과정 없이 배포가 가능하다. (보통 code-push라는 라이브러리를 사용하는 듯.) 따라서 사용자 반응에 민감한 앱의 경우, 빠르게 피드백을 반영할 수 있다.
강력한 포팅
React로 구현된 웹을 모바일로 빠르고 간편하게 포팅할 수 있다. 역방향도 가능.
다양한 디버깅 툴
개발자 메뉴에 빠르게 접근할 수 있다.
Fast Refresh가 가능하다.
Chrome, Safari, React 개발자 툴을 사용할 수 있다.
앱 상태 디버깅용 서드파티 라이브러리가 존재한다.
react-debtools를 이용해서 컴포넌트 트리와 속성 스타일등을 확인할 수 있다.
단점
크로스 플랫폼
장점이자 단점. 결국 플랫폼마다 특별한 UI가 존재하기 때문에, 플랫폼을 확인하고 그에 따라 분기처리를 해야 한다. 특히 UI 부분에 대해, 동일한 컴포넌트가 서로 다른 속성을 필요로 하는 경우가 잦다.
성능 및 한계
- 성능이 아무래도 네이티브보단 후달린다. 아무래도 레이어를 하나 더 추가하는 셈이니까..
- 100% 네이티브하지 못함. 어찌됫건 네이티브한 부분을 건드려야 할 상황이 발생할 확률이 높음.
- 복잡한 UI나 애니메이션은 구현하기 힘듦.
그래도 여전한 러닝커브
앱에 대해 무지하다면 환경설정, 개발, 빌드, 배포까지에 대한 이해가 필요하다. 심도있는 기능이나 최적화를 위해서는 네이티브 언어를 알아야 한다.
웹과 다른 문법
특히 스타일링에 관해서 매우 힘들다.
- 지원되지 않는 속성도 많다. (대표적으로
display: fixed
가 지원되지 않는다.)
- 스타일 오버라이딩도 꼼꼼히 해야 한다. (
marginTop
과marginBottom
속성을marginVertical
로 오버라이딩 할 수 없음.)
- 가상클래스, 가상요소(
::after
,::before
) 등을 쓸 수 없다.
참고 : https://wit.nts-corp.com/2020/03/23/6014
디버깅 및 유지보수
이슈가 RN측 이슈인지 네이티브측 이슈인지 파악하기 힘들다.
아무리 디버깅 툴이 잘 되어 있다고 해도, 웹 디버깅 툴보다 못하다.
- 스타일 속성 추가 및 값 변경으로 다양한 테스트를 해보고 싶어도 핫 리로딩에 스타일이 안먹는 경우가 잦다.
- UI 인스펙터에 대해, 웹보다는 조금 불편한 감이 있다. (이것은 react-devtools로 해결 가능)
- 모달 창의 경우, 인스펙터를 켜면 사라지는 현상이 있다. (물론 이 때 UI 인터렉션이 되지 않아 모달 창을 켤 수 없다.)
- react-devtools 를 이용할 때, 스타일 속성 추가는 되지만 제거는 되지 않는다.