React를 사용한 웹개발 경험이 있으면, React Native를 이용한 앱개발을 고려하게 됩니다.
React Native를 이용하여 앱을 개발시 미리 알았더라면 하는 내용입니다.

1. React로 웹 개발해 봤으면 바로 시작 할 수 있는거 아냐?

React로 웹을 만들어 봤으면 동일한 구조로 진행 할 수는 있습니다.

<div>는 <View>로 바꾸고, <span>은 <Text>로 바꾸면 끝이다라는 글을 보고 매우 쉽게 생각하였습니다.

1 - 1. 기기별 호환성

웹 개발을 할 때, 브라우저별 호환성을 고려해야 합니다.
크로스 브라우징 문제는 특히 한국(Internet Explorer)에서 대응을 해야 되는 문제로 개발자를 힘들게 합니다.
앱 개발시에는 이러한 문제점이 없을 거라고 생각하였지만, 큰 오해였습니다.
기기마다 OS 버전이 달라서 공통으로 적용 할 수 있는 네이티브 API에 대한 고려를 해야 됩니다.
웹은 버전이 올라갈수록 이용 할 수 있는 API 및 CSS가 하위 버전을 포괄 하였지만, 앱쪽은 꼭 그렇지가 않습니다.
오히려 OS 버전이 올라갈수록(안드로이드 기준) 보안문제로 이용 할 수 있는 API가 제한되기도 합니다.

1 - 2. 스타일

모바일은 같은 OS 버전의 기기라도, 기기별 스크린(가로, 세로 크기)이 모두 다 다릅니다.
이러한 점 때문에 React Native는 flexbox를 활용한 레이아웃 제작이 기본으로 제공됩니다.
그러나 모든 스크린을 완벽하게 대응 할 수 없기에 항상 여러 기기에서 UI 결과를 보면서 진행 하여야 합니다.

(당연한 이야기 이지만)웹 개발 처럼 scss기반으로 css를 작업 할 수 없습니다.
모든 컴포넌트에 스타일을 지정하면서 작업(단순 css처럼)하여야 해서 가독성이 떨어지는 문제가 있습니다.

또한, (이것도 당연한 이야기 이지만)글로벌 스타일 정의가 불가능 합니다.
보통 웹 개발시에는 index.css에 글로벌하게 적용하고 싶은 스타일을 지정합니다.
(styled-components 이용시 createGlobalStyle을 이용한 글로벌 스타일 정의)
그러나 React Native에서는 이러한 개발이 불가능 합니다.
그렇게 때문에 개발 시작전에 폰트 및 테마를 기본 컴포넌트에 정의하고, 정의한 컴포넌트를 사용하여 작업을 진행하여야 합니다.

1 - 3. 리액트와 조금 다른 점들

react native로 여러 스크린을 만들면 react navigation을 이용하게 됩니다.
그러나 react와 동작 방식이 조금 다릅니다.
react-router-dom은 stack을 중첩하지 않습니다.
보통 페이지별로 Switch 컴포넌트 내에서 페이지별로 Route를 정의하게 됩니다.
react navigation은 stack을 중첩하여 스크린을 제공하므로, 작동 방식이 조금 다릅니다.
react navigation도 switch 컴포넌트를 제공하지만, 보통은 token 유효 여부를 판단하여 로그인에 대한 핸들링을 하는곳에 주로 이용을 합니다.
스택은 중첩되므로 최초 스크린 진입후에 재진입시에는 다시 mount가 되지 않습니다.
mount가 다시 되지 않기때문에 componentDidMount같은 라이프 사이클 적용 방식을 다르게 해야합니다.
react navigation에서 자체적으로 스크린이 포커싱에 대한 라이프사이클을 제공합니다.
또한, 기존의 앱들처럼 하단 네비게이션 탭등 자체적으로 많은 지원을 해주기 때문에, react navigation에 대한 숙지가 필요합니다.

2. IOS와 Android 동시 개발

React Native는 양쪽 플랫폼 개발을 모두 지원하는 것이 맞습니다.
그러나 아무 생각없이 UI 만들고, React Native에서 지원하는 API를 마구 이용한다면 양쪽 플랫폼을 동시에 대응하는 앱을 만드는 것은 매우 힘듭니다. 당연히 양쪽 플랫폼의 OS는 아예 다르고 각 OS별 버전이 다르므로, 이를 모두 고려하면서 개발을 하여야 합니다.
플랫폼 별 정책 또한 매우 다르므로, 한가지 프로젝트에서 양 플랫폼을 개발하려 한다면, 진행전 각 플랫폼에 대한 정책을 상세히 파악 후 진행하여야 합니다.

3. 네이티브 개발 언어 대비 성능

React Native는 javascript 기반으로 개발이고, 브릿지를 통해 네이티브 API를 호출하여 앱을 동작시킵니다.
브릿지 병목 현상 및 네이티브 앱 대비 성능을 문제로 지적하는 글들이 많습니다.
그러나, 복잡한 앱 개발 및 애니메이션 구현이 아니라면 성능에 대한 문제를 느끼지 못하였습니다.
개발자가 로직만 잘 구축한다면, 성능도 매우 훌륭하고, 생산성에 대한 이점도 얻을 수 있습니다.

4. react native init vs expo init

React Native를 시작하게 되면 두 가지 방법으로 프로젝트를 시작 할 수 있습니다.

react native init은 기본적으로 제공되는 API를 이용하다가, 필요한 모듈이 있으면 직접 만들어서 사용 할 수 있습니다.
그러나 초기 개발 환경 세팅 및 관리 운영에 조금 더 공수가 들어가게 됩니다.

expo는 초기 공수가 매우 적게 들어가는 장점이 있습니다.
android studio나 xcode도 설치 안하고 진행 할 수 있습니다. expo-cli로 프로젝트를 생성 후, expo client를 모바일에 설치하면 개발 환경 세팅이 완성됩니다. 또한 expo 에서 자체적으로 제공하는 API들을 이용하면 정말 수월하게 입문 할 수 있습니다.

그러나 expo는 단점이 명확합니다.

  • 빌드 파일 크기가 매우 크다
  • 제공하는 API만 이용이 가능하다(직접 모듈 제작 불가능)
  • 블루투스 이용 불가
  • 백그라운드 직접 핸들링 불가능
  • hermes 엔진등 최신 스펙 이용 불가(현재 expo 버전 기준 0.60 이용불가)
  • 매우 좁은 생태계

한국에서 서비스 한다면, 네이버맵, 카카오맵등 지역 기반 모듈도 이용이 불가능합니다
(구글맵만 제공)
아직은 expo로 규모가 크고 기능이 많은 앱을 개발하는 것은 어려움이 많습니다.

5. Flutter vs React Native

Flutter를 사용해보지 않아 비교가 불가하지만,
React에 익숙하고 javascript에 익숙하다면,
React Native를 선택하지 않을 이유는 없습니다.

6. 정적 타입 언어 도입(flow, typescript..)

flow는 도입을 하지 않아서 명확하게 파악이 불가능합니다.
typescript에 익숙하지 않다면, 직접 모듈에 대한 정의나 타입을 타이트하게 정의하는 것이 쉽지 않습니다.
react native에 익숙하지 않다면, 외부 모듈을 적극적으로 이용 하여 개발을 하는 것도 좋은 방법입니다.
react 만큼 생태계가 크지 않아, typescript 기반의 모듈도 적고 @types에 정의 되지 않은 모듈도 많습니다.

거기에 expo를 이용하여 프로젝트를 진행한다면 더욱 생태계가 더욱 좁아지게 됩니다.
expo에 typescript를 적용한다면 생태계는 매우 매우 좁아집니다.
expo 자체는 tyepscript로 제작 되었지만, 서브 모듈은 그렇지가 않습니다.

결론

React Native를 입문한다면 typescript 미적용을 추천드립니다.
expo는 단점이 많지만 직접 프로젝트를 구축한다면 프로젝트를 진행하기도 전에 지칠 수 있으므로,
학습 용도로 expo를 사용하는 것은 매우 좋은 선택입니다.
그러나 조금 더 깊이 있는 앱을 만드신다면 직접 구축!