Framework/React & RN

ReactNative 개발, 어떻게 시작하면 좋을까?

Joonfluence 2021. 12. 29.

서론

대상독자

React 개발을 경험이 있으나, 처음 React Native(이하 RN)으로 앱 개발을 하려는 프론트엔드 개발자

학습목표

리액트와 RN의 차이점을 알고 그 차이가 어디에서 비롯되는지 이해한다.
네이티브 앱과 RN의 차이점을 알고 RN의 한계점에 대해서 이해한다.
RN 개발환경을 이해하고 상황에 맞게 능동적으로 선택할 수 있다.
Expo와 React Native Init 간 차이점을 알고 장/단점을 설명할 수 있다.

본론

리액트와의 차이점

RN을 활용하면, 리액트에서 자주 활용했던 jsx 문법, 라이프사이클 함수, react hooks, 함수형/클래스형 컴포넌트 등을 활용할 수 있습니다. 그래서 공통점을 언급하는 것보다는 차이점에 대해서 중점을 두고 설명해보려 합니다. 웹이 아닌 앱 개발에 리액트를 활용하는 것이기 때문에, 조금 차이가 있습니다.

첫째, 클라이언트에서 활용할 수 있는 데이터베이스가 다릅니다. 따라서 인증기능을 구현할 때, 차이가 있습니다. 웹에서는 유저의 인증정보를 쿠키에 주로 저장하죠. 세션이 아니라 쿠키(혹은 LocalStorage)로 저장하는 까닭은 작은 용량이지만 사용자 수가 늘어남에 따라 서버에 부담을 줄 수 있기 때문입니다. 또한 관리하기도 어렵다는 단점이 있죠. 그래서 브라우저에 저장될 수 있는 쿠키에 암호화시켜 정보를 저장함으로써, 유저를 식별하곤 합니다. (그래서 쿠키를 제거하면 사이트의 로그인이 풀리는 까닭도 그러한 이유에서이죠.) RN 앱에서는 쿠키와 비슷한 역할(정확히는 웹의 LocalStorage와 같습니다)을 해주는 모듈이 따로 존재합니다. Asyncstorage입니다. 해당 모듈에서 제공하는 메소드들을(setItem, getItem 등) 활용하면, 쉽게 원하는 기능을 구현할 수 있습니다.

둘째, RN에서는 가상 DOM을 렌더링하지 않습니다. 따라서 웹 개발을 하면서 주로 쓰던 HTML 태그들을 (div/span/button/input 등) RN에서 제공하는 컴포넌트들로 대체해줘야 합니다. 구체적으로 div는 View 컴포넌트로, span은 Text 컴포넌트로, button은 Button 컴포넌트로, input은 TextInput 컴포넌트로 대체할 수 있습니다. 더욱 다양한 정보들을 확인하려면 해당 페이지를 참조해주시기 바랍니다.

셋째, 이벤트 핸들링 방식에 차이가 있습니다. 대표적인 예시가 button 컴포넌트의 onPress 함수에서 주로 호출되는 PressEvent 일 것입니다. 웹에서의 클릭 이벤트와는 attribute에서 차이가 있습니다. 이와 관련해서는 공식문서에 자세한 설명이 나와있으므로, 참조 링크로 갈음하겠습니다. 

넷째, 스타일링 방식에 차이가 있습니다. 스타일링의 제약조건이 없는 웹과는 다르게, RN에선 flex 기반 스타일링입니다. 그래서 CSS Flexbox에 대해, 이미 사용해본 경험이 있는 분들에게는 횔씬 수월할 수 있습니다. 더 자세한 설명은 참조 링크를 참조해주시길 바랍니다.

네이티브 앱과의 차이점

첫째, 리액트 네이티브의 한계점은 네이티브에서 지원하는 다양한 애니메이션 기능들을 지원하지 않는다는 점입니다. 만약 복잡한 애니메이션 기능을 화면에서 구현해야 한다면, 네이티브 코드를 직접 작성해서 구현해야 한다는 단점이 있습니다.

둘째, 지원되는 라이브러리의 수가 부족합니다. 이는 개발 생산성에 크게 영향을 미칠 수 있습니다.

셋째, 개발 버젼이 변경될 때마다 기존 패키지들과 호환되는지 여부를 따져줘야 합니다. 외부 패키지들이 많은 리액트 네이티브에서 해당 부분 역시, 개발 생산성에 큰 영향을 미칠 수 있습니다.

그 외에도 다양한 차이점이 존재합니다. 더 이상의 내용을 알아보고 싶은 분들은 관련한 포스팅에서 참고해주시면 좋을 것 같습니다.

React Native의 역할은?

React Native App 구조도

RN의 기능 중 가장 중요한 것은 자바스크립트 코드가 아니라, Bridge들을 통해서 코드가 운영체제와 통신을 할 수 있도록 하는 인프라시설입니다. RN은 자바스크립트와 Native 간 마치 운영체제의 쉘과 같은 역할을 해줍니다. 자바스크립트 코드를 작성하면, 해당 코드가 각각의 운영체제(ios, Android)에서 작동할 수 있도록 돕습니다. 이는 각각의 Native Thread와 통신함으로써 가능합니다. 이런 점에서 앱 내에 브라우저를 내장시킴으로써 동작하는 웹 뷰 앱과의 차이점이 생깁니다. RN에선 네이티브 코드로 배포되기 때문이죠. 따라서 하이브리드 앱이라기보단 네이티브 앱의 성격에 더 가깝다고 볼 수 있습니다. (Flutter의 경우에는 하이브리드 앱이지만, 자체 렌더링 엔진을 갖고 있기 때문에 특이한 케이스입니다.) 

Javascript와 Native 간의 통신 구조도

실제 사용자의 동작에 따라, 조금 더 자세히 설명드리자면 앱에서 버튼 이벤트가 발생했다고 가정해보겠습니다.

1) Native(IOS, Android) 단계에서 버튼 클릭 이벤트가 발생합니다.
2) 해당 버튼이 어떤 방식으로 동작했는지에 관한 정보가 생성되며, 이와 관련된 모든 정보는 Native 레벨에서 통제됩니다.
3) 브릿지 역할을 하는 RN은 해당 데이터를 JSON 데이터로 Serialized 해, 데이터를 JS로 전송합니다.
4) 자바스크립트는 해당 데이터를 전달 받습는다.
5) 자바스크립트에선 새로운 메세지를 RN을 통해 Native로 전송되도록 요청합니다.
6) RN이 데이터를 JSON 데이터로 Serialize 해, Native에게 전송합니다. 
7) 해당 메세지를 읽습니다.
8) Native는 해당 메시지를 바탕으로 동작을 수행합니다.

환경설정

자, 이제 리액트 네이티브에 대해 조금 더 자세하게 알아보도록 하겠습니다. 리액트 네이티브 개발에 빼놓을 수 없는 부분이 바로 환경설정 부분인데요, 해당 부분을 설명하면서 React Native Init 을 통한 환경설정 방법과 Expo를 통한 방법을 비교해보도록 하겠습니다. 

Expo (create-react-native-app)

Expo에서는 이미 앱이 컴파일된 상태이며, Google Playstore와 App Store에 배포되어 있습니다. 따라서 개발자 입장에서는 expo를 활용하면 빠르게 배포할 수 있게 되는 것이죠. 실제로 Expo Go App을 다운로드 받으면, qr 링크를 통해 실 디바이스에서도 빠르게 개발된 프로그램을 확인할 수 있습니다. 위 다이어그램 Expo에선 비어있는 코드 부분(JavaScript, Markup/Styling)을 작성해서 채워 넣으면 되는 것입니다.

장점

  • 환경설정이 쉽습니다. expo cli를 통해, 모든 번거로운 과정들을 expo에서 처리해줍니다.
  • 앱을 실행하기 위해서 빌드해줄 필요가 없습니다. 이는 개발 생산성 면에서 정말 큰 차이가 납니다.
  • expo에서 제공하는 라이브러리와 통합하기가 매우 쉽습니다. Push Notification이나 Asset Manager 등이 그러하죠.
  • 언제든지 eject 하고 expo 기능을 활용하면서도 Native 코드와 통합시킬 수 있습니다.
  • expo에서도 .apk와 .ipa 파일로 빌드가 가능합니다.

단점

  • 네이티브 모듈에 접근이 불가능합니다.
  • Objective-C/Java로 쓰인 라이브러리를 활용할 수 없습니다.
  • 용량이 무지 큽니다. 아무런 기능이 없는 Expo 앱도 25MB가 넘습니다. expo에 기본적으로 설치된 라이브러리들 때문이죠.
  • expo 생태계에 없는 기능들을 추가하려면, eject 해줘야 합니다. 대표적으로 화면인식, 결제, ARKit 등을 쓰려면 말이죠.
  • Eject하는 동시에, qr 코드로 앱에 접근하는 기능은 사라지게 됩니다.
  • Eject하면 RN 버젼에 제약이 걸리게 됩니다. Expo와 호환되는 RN 버젼으로 고정되어 있기 때문이죠. 따라서 향후 유지보수에 문제가 발생할 가능성이 높아집니다.
  • Expo에서 네이티브 모듈에 대한 디버깅하기가 정말 어렵습니다. Expo에서 공식적으로 지원해주지도 않죠.

React Native init

반면 이러한 기능들을 제공하는 Expo를 사용하지 않고 React Native Init을 통해, 프로젝트를 환경 설정을 해줄수도 있습니다.

장점

  • 네이티브 모듈에 접근 가능하므로, 해당 코드들을 수정하거나 모듈을 추가해줄 수 있다는 점입니다.

단점

  • Android Studio와 Xcode(Mac book에서만 가능함)로 직접 빌드해줘야 합니다.
  • 테스팅 할 때 USB로 직접 실 디바이스와 연결해서 진행해줘야 합니다. 물론 에뮬레이터로 테스팅을 할 수도 있습니다.
  • 또한 다른 사람에게 작업 내용을 공유하려면 .apk나 .ipa file 단위로 가능합니다. 배포되기 전까지 말이죠.
  • Push-Notifications, Asset Manager 등의 기능들도 외부 라이브러리를 통해 통합 해줘야 합니다. 단, 버젼 관리가 꽤 지랄 맞습니다.
  • 프로젝트 환경설정도 까다롭습니다. 다양한 디바이스 설정을 제대로 맞춰줘야 하기 때문입니다.

결국, 어떤 걸 선택하면 좋을까?

이건 각자의 상황에 따라 다르다고 생각합니다. 저 같은 경우에는 혼자서 RN 개발을 하고 있기 때문에 Expo를 활용해서 프로젝트를 진행 중에 있습니다. RNI로 셋업 했을 때, 가장 답답한 부분은 새로운 라이브러리를 추가해줬을 때, 테스트하기 위해선 새롭게 빌드를 해줘야하고 의존성 문제를 Xcode와 Android Studio에서 처리해주는 것이었습니다. 개발하기에도 많은데, 패키지 의존성 관리하느라 정작 개발에 시간을 쏟기 어려웠습니다.

그러나 엔터프라이즈 레벨에서 사용한다면, 이야기가 달라질 수 있을 것 같습니다. 팀에 프론트 시니어 개발자가 있다면, RNI로 프로젝트를 셋업해도 좋을 것이란 생각이 듭니다. 용량 면에서 차이가 나기 떄문입니다. 또한 네이티브 앱으로 이미 개발된 앱을 RN으로 포팅할 때도 RNI가 더 유리할 것이라 생각됩니다.

그 외에도 Expo에서 지원해주는 패키지가 아니라면, eject 해줘야 할 수도 있습니다. 예를 들어, Naver와 카카오 등의 소셜로그인 기능을 구현하려면 eject 해줘야 하는 것으로 알고 있습니다.

마무리

이상으로 관련 포스팅은 마무리하도록 하겠습니다. 꽤나 긴 글을 읽어주셔서 감사드리며, 프로젝트 진행에 있어 이 글이 시간을 단축하는데 도움이 되셨으면 좋겠습니다. 감사합니다.

참고한 사이트

Asyncstorage
[RN] React-Native의 장단점은?
React Native CLI vs Expo CLI — Which one do I choose?
[React Native] 리액트 네이티브란? 장단점
02. 리엑트 네이티브의 동작 방식 - 브릿지, 가상돔
[모바일] 네이티브앱 vs 모바일웹앱 vs 하이브리드앱

반응형

댓글