react native 공식문서의 내용을 번역하며 공부했습니다. 제가 이해하기 편하도록 수정한 부분도 있을겁니다...
네이티브 모듈과 네이티브 컴포넌트는 레거시 아키텍처에서 사용되는 안정적인 기술입니다.
이후에 새로운 아키텍처가 안정화되면 더 이상 사용되지 않을 것 입니다.
새로운 아키텍처는 커보 네이티브 모듈과 패브릭 네이티브 컴포넌트를 사용해서 유사한 결과를 달성합니다.
최신 앱에서 사용할 수 있는 수 많은 네이티브 UI 위젯이 있으며, 그 중 일부는 플랫폼의 일부로 제공되고, 일부는 서드파티 라이브러리로 제공되며, 더 많은 위젯이 포트폴리오에서 사용될 수 있습니다.
리액트 네이티브에는 ScrollView와 TextInput과 같은 가장 중요한 플랫폼 컴포넌트 몇 가지가 이미 래핑되어있지만, 모든 컴포넌트가 래핑된 것은 아니며 이전 앱에서 직접 작성했을 수도 있습니다.
다행히도 이러한 기존 컴포넌트를 래핑하여 리액트 네이티브 애플리케이션과 원활하게 통합할 수 있습니다.
네이티브 모듈 가이드와 마찬가지로, 이 가이드 역시 iOS 프로그래밍에 어느 정도 익숙하다고 가정하는 고급 가이드입니다.
이 가이드에서는 네이티브 UI 컴포넌트를 빌드하는 방법을 보여드리며, 핵심 리액트 네이티브 라이브러리에서 사용할 수 있는 기존 MapView 컴포넌트의 하위 집합을 구현하는 과정을 안내합니다.
앱의 MapView를 추가하고 싶다고 가정해 보겠습니다.
MKMapView를 사용하면 자바스크립트에서 사용할 수 있게 만들 수 있습니다.
NativeView는 RCTViewManager의 서브클래스에 의해 생성되고 조작됩니다.
이러한 서브클래스는 뷰 컨트롤러와 기능이 비슷하지만 본질적으로 싱글톤이며, 브릿지에 의해 각각 하나의 인스턴스만 생성됩니다.
이 서브클래스는 네이티브 뷰를 RCTUIManager에 노출하고, 이 서브클래스는 필요에 따라 뷰의 프로퍼티를 설정하고 업데이트하기 위해 다시 위임합니다.
또한 RCTViewManagers는 일반적으로 View의 Delegate가 되어 브릿지를 통해 이벤트를 자바스크립트로 다시 전송합니다.
- (UIView *) view
메서드를 구현합니다.#import <MapKit/MapKit.h>
#import <React/RCTViewManager.h>
// 1. RCTViewManager 클래스를 확장한 RNTMapManager 정의
// RNTMapManager.h파일로 분리할 수 있다
@interface RNTMapManager : RCTViewManager
@end
// 2. 모듈이름정의: 리액트 네이티브에서 NativeModules.RNTMap으로 조회됨
@implementation RNTMapManager
RCT_EXPORT_MODULE(RNTMap)
- (UIView *)view
{
return [[MKMapView alloc] init];
}
@end
- (UIView *)view
메서드를 통해 노축하는 UIView 인스턴스에서 frame 또는 배경색 속성을 설정하려고 시도하지 마세요
리액트 네이티브는 자바스크립트 컴포넌트의 레이아웃 프로퍼티와 일치하도록 사용자 정의 클래스에서 설정한 값을 덮어씌웁니다.
이러한 세분화된 제어가 필요한 경우 스타일을 지정하려는 UIView 인스턴스를 다른 UIView로 래핑하고 대신 래퍼 UIView를 반환하는 것이 더 나을 수도 있습니다.
위의 예시에서는 클래스 이름앞에 RNT
를 붙였습니다.
접두사는 다른 프레임워크와의 이름 충돌을 피하기 위해 사용됩니다.
Apple 프레임워크는 두 글자로 된 접두사를 사용하며, 리액트 네이티브는 접두사로 RCT를 사용합니다.
이름 충돌을 피하기 위해서는 자체 클래스에서는 RCT가 아닌 세 글자 접두사를 사용하는 것이 좋습니다.
그런 다음 이것을 사용 가능한 리액트 컴포넌트로 만들려면 약간의 자바스크립트가 필요합니다.
// MapView.js
import { requireNativeComponent } from 'react-native';
export default requireNativeComponent('RCTMap');
import MapView from './MapView';
return <MapView style={{flex:1}}/>