[번역] React Native 0.78 - React 19와 그 외의 기능

오성준·2025년 3월 4일

React Native

목록 보기
12/16

오늘 React Native 0.78을 출시하게 되어 기쁩니다!

이번 릴리스에는 React Native의 React 19와 Android Vector drawables에 대한 native 지원 및 iOS용 브라운필드 통합 개선과 같은 기타 관련 기능이 포함되어 있습니다.

하이라이트

  • React 19
  • 더 작고 빠른 릴리스를 향해
  • Metro에서 JavaScript 로그 옵트인
  • Android XML drawables에 대한 지원 추가
  • iOS의 ReactNativeFactory

하이라이트

React 19

이제 React 19를 React Native에서 사용할 수 있습니다!

React 18에서 몇 가지 변경 사항이 도입되었기 때문에 React 19를 사용하려면 앱을 업데이트해야 합니다. 예를 들어 propTypes와 같은 일부 API가 제거되었으므로 새 버전의 React와 호환되도록 앱을 조정해야 합니다.

단계별 지침에 따라 앱을 React 19로 업그레이드하세요.

마이그레이션 후에는 (전부는 아니지만) React의 새로운 기능을 활용할 수 있습니다.

  • Actions: 비동기 전환을 사용하는 함수입니다. 비동기 전환은 pending 상태, 낙관적 업데이트, 에러 핸들링 등을 처리하는 등 데이터 제출을 자동으로 관리합니다.
  • useActionState: Actions 위에 구축된 유틸리티 hook입니다. 함수를 받아 호출할 래핑된 Action을 반환합니다. Action이 호출되면 Action의 마지막 결과와 pending 상태를 반환합니다.
  • useOptimistic: 비동기 요청이 진행되는 동안 업데이트의 최종 상태를 낙관적으로 표시하는 것을 간소화하는 새로운 hook입니다. 요청에 오류가 발생하면 React는 자동으로 이전 값으로 다시 전환합니다.
  • use: 렌더링 중에 리소스에 액세스할 수 있는 새로운 API입니다. 이제 use로 promise나 context를 읽으면 해결될 때까지 React가 Suspend됩니다.
  • 프로퍼티로서의 ref: 이제 다른 프로퍼티와 마찬가지로 프로퍼티에 ref를 전달할 수 있습니다. 함수 컴포넌트에는 더 이상 forwardRef가 필요하지 않으며 이제 컴포넌트를 마이그레이션할 수 있습니다.
  • 그리고 그 외 많은 것들

사용 가능한 새로운 기능의 전체 목록은 React 19 릴리스 블로그 게시물을 참조하세요.

React 컴파일러

React 컴파일러는 메모이제이션을 자동으로 적용하여 React 애플리케이션을 최적화하도록 설계된 빌드 타임 툴입니다. 개발자는 useMemo, useCallback, React.memo와 같은 API를 수동으로 사용하여 앱의 변경되지 않은 부분을 불필요하게 재계산하는 것을 방지할 수 있지만, 이러한 최적화를 잊거나 오용할 수도 있습니다. React 컴파일러는 JavaScript와 React의 규칙에 대한 이해를 활용하여 컴포넌트와 hook 내에서 값 또는 값 그룹을 자동으로 메모이제이션함으로써 이 문제를 해결합니다.

이번 릴리스에서는 React Native 앱에서 React 컴파일러를 활성화하는 프로세스가 간소화되었습니다. 이전 버전에서는 컴파일러와 런타임이라는 두 가지 패키지를 설치해야 했습니다. 이 패키지를 설치한 후에는 Metro를 통해 React 컴파일러를 활성화하기 위해 Babel 플러그인을 구성해야 했습니다.

이제 컴파일러 자체만 설치하고 Babel 플러그인을 구성하기만 하면 됩니다. 활성화하는 방법을 알아보려면 단계별 가이드를 참조하세요.

컴파일러가 실행 중인지 확인하려면 컴포넌트 인스펙터에서 메모된 컴포넌트에 Memo ✨ 태그가 붙어있는 것을 확인하면 됩니다.

React 컴파일러에 대해 자세히 알아보고 싶다면 유용한 리소스를 참고하세요.

더 작고 빠른 릴리스를 향해

2025년에는 안정적인 React Native 릴리스를 더 자주 출시하기 위해 릴리스 프로세스를 업데이트할 예정입니다.

릴리즈 횟수가 줄어들기 때문에 React Native 버전을 업데이트하기가 더 쉬워질 것입니다. 또한 릴리스가 빨라진다는 것은 내부에서 제공하는 모든 버그 수정이 더 빨리 여러분에게 전달되고, React Native 내부에서 개발하는 최신 기능의 혜택을 누릴 수 있다는 의미이기도 합니다.

이 새로운 모델은 급격한 변경이 적다는 것은 모두가 신뢰할 수 있는 안정적인 프레임워크를 의미하므로 React Native 생태계의 모든 개발자에게 도움이 될 것이라고 믿습니다.

Metro에서 JavaScript 로그 옵트인

커뮤니티 CLI 사용자를 위해 0.77에서 제거되었던 Metro 개발 서버를 통한 JavaScript 로그 스트리밍을 복원하는 옵트인 기능을 추가했습니다. 이는 사용자 피드백에 대한 응답이자 현재 대체 기능에 대한 검토 결과입니다.

옵트인하려면 새로운 --client-logs 플래그를 사용합니다. 편의를 위해 npm 스크립트를 통해 별칭을 지정할 수도 있습니다.

npx @react-native-community/cli start --client-logs

Metro의 로그 스트리밍은 향후에도 계속 사용되지 않으며 기본적으로 꺼진 상태로 유지됩니다. 하지만 개발자가 이 변경에 적응할 수 있도록 마이그레이션 기간을 더 길게 부여할 계획입니다.

이 업데이트는 곧 출시될 0.77.1 마이너 릴리스에서도 제공될 예정입니다.

Android XML drawable에 대한 지원 추가

React Native 0.78에서는 Android에서 아이콘, 일러스트레이션 및 기타 그래픽 요소를 XML resources로 로드하는 새로운 방법을 제공합니다. 즉, vector drawables을 사용하여 품질 저하 없이 모든 스케일의 벡터 이미지를 표시하거나 shape drawables을 사용하여 보다 기본적인 장식을 그릴 수 있습니다. 이 모든 것은 여러분이 잘 알고 있는 동일한 Image 컴포넌트에서 지원됩니다. 지금 이 기능을 사용하려면 다른 정적 리소스와 마찬가지로 source 프로퍼티에서 참조하여 XML 리소스를 가져올 수 있습니다. 또한 비트맵 대신 XML 리소스를 사용하면 애플리케이션 크기를 줄이는 데 도움이 되며 다양한 DPI의 화면에서 더 나은 렌더링을 얻을 수 있습니다.

// via require
<Image
  source={require('./img/my_icon.xml')}
  style={{width: 40, height: 40}}
/>;

// or via import
import MyIcon from './img/my_icon.xml';
<Image source={MyIcon} style={{width: 40, height: 40}} />;

성능 및 품질

다른 모든 이미지 유형과 마찬가지로 Android의 XML 리소스는 메인 스레드에서 로드되고 부풀려지므로 프레임이 떨어지지 않습니다. 즉, 리소스가 즉시 표시된다는 보장은 없지만 리소스가 로드되는 동안 사용자 입력이 차단되지 않습니다. Off-thread decoding은 많은 아이콘을 동시에 렌더링해야 할 때 특히 중요합니다. 내부 앱은 Android의 vector drawable을 사용할 때 상당한 성능 향상을 실현했습니다.

vector drawable과 같은 리소스 유형을 활용하면 품질 저하 없이 이미지를 표시할 수 있으며, 모든 화면 밀도에 대해 이미지 유형을 포함할 필요가 없으므로 APK 파일 크기를 줄일 수 있습니다. 또한 vector drawable은 로드되면 메모리에서 복사되므로 동일한 아이콘을 두 번 이상 렌더링하면 모두 동시에 표시됩니다.

트레이드 오프

drawable XML 리소스는 완벽하지 않으며 이를 사용하는 데 제약이 있다는 점에 유의해야 합니다.

  • 이러한 리소스는 Android 애플리케이션 빌드 시 참조해야 합니다. 이러한 리소스는 Android Asset Packaging Tool(AAPT)을 사용하여 빌드 단계로 전달되어 raw XML을 바이너리 XML로 변환합니다. Android는 raw XML 파일 로드를 지원하지 않으며, 이는 알려진 제한 사항입니다.
  • 이러한 리소스는 Metro에서 네트워크를 통해 로드할 수 없습니다. XML 리소스의 디렉토리 또는 이름을 변경하는 경우 매번 Android 애플리케이션을 다시 빌드해야 합니다.
  • dimension이 없습니다. 기본적으로 0x0 크기로 표시되며 표시하려면 width와 height를 입력해야 합니다.
  • 런타임에 완전히 커스터마이징할 수는 없으며, dimension이나 전체 tint color만 제어할 수 있고 stroke width, border radius 또는 색상과 같은 리소스 내부의 개별 요소 속성은 사용자 지정할 수 없습니다. 이러한 유형의 사용자 지정에는 XML 리소스의 다양한 변형이 필요합니다.

정보
Android의 vector drawable은 react-native-svg와 같은 라이브러리를 1:1로 대체할 수 없습니다. XML 리소스는 Android용으로 특별히 설계되었으며 iOS에서는 작동하지 않습니다. 모든 플랫폼에서 동일한 SVG를 사용하려면 react-native-svg를 계속 사용해야 합니다. vector drawable은 커스터마이징을 희생하는 대신 성능상의 이점을 제공할 뿐입니다.

iOS의 ReactNativeFactory

React Native 0.78에서는 iOS에서 React Native의 통합을 개선했습니다.

이 버전에서는 AppDelegate 없이도 React Native의 인스턴스를 생성할 수 있는 RCTReactNativeFactory라는 새로운 클래스가 도입되었습니다. 이를 통해 예를 들어 ViewController에서 새로운 버전의 React Native를 생성할 수 있습니다. 이렇게 하면 브라운필드 앱과의 통합이 크게 간소화됩니다.

앱의 View Controller에 React Native 뷰를 표시하고 싶다고 가정해 봅시다. 이 가이드에 표시된 대로 모든 종속성을 설치한 후 React Native 0.78부터 이 코드를 추가하면 됩니다.


+import React
+import React_RCTAppDelegate

public class ViewController {

+  var reactNativeFactory: RCTReactNativeFactory?
+  var reactNativeDelegate: ReactNativeDelegate?

  public func viewdidLoad() {
    super.viewDidLoad()
    // …
+ reactNativeDelegate = ReactNativeDelegate()
+ reactNativeFactory = RCTReactNativeFactory(delegate: reactNativeDelegate!)
+ view = reactNativeFactory.rootViewFactory.view(withModuleName: "<your module name>")
  }

}

+class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {

+  override func sourceURL(for bridge: RCTBridge) -> URL? {
+    self.bundleURL()
+  }
+
+  override func bundleURL() -> URL? {
+    #if DEBUG
+    RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
+    #else
+    Bundle.main.url(forResource: "main", withExtension: "jsbundle")
+    #endif
+  }
+}

View Controller로 이동하자마자 React Native가 View Controller에 로드됩니다.

이 코드는 RCTReactNativeFactory를 생성하고, 델리게이트를 할당하고, React Native의 뷰에 대한 rootView를 생성하도록 요청합니다.

델리게이트는 아래에 정의되어 있으며, sourceURLbundleURL 프로퍼티를 재정의하여 React Native가 뷰에서 로드할 JS 번들을 찾을 수 있는 위치를 알려줍니다.

다른 Breaking Changes

일반

  • React Native DevTools
    • FuseboxClient CDP 도메인 제거
  • Codegen
    • 컴포넌트 배열 타입과 명령 배열 타입 분리

Android

  • Nullability changes: RootView를 Kotlin으로 마이그레이션하면서 매개변수 타입이 nullable에서 non nullable로 변경되었습니다.
  • 다음 클래스는 public에서 internal로 이동되었거나 제거되어 더 이상 액세스할 수 없습니다.
    • com.facebook.react.bridge.GuardedResultAsyncTask
    • com.facebook.react.uimanager.ComponentNameResolver
    • com.facebook.react.uimanager.FabricViewStateManager
    • com.facebook.react.views.text.frescosupport.FrescoBasedReactTextInlineImageViewManager

iOS

  • 이미지 로드 이벤트 크기 정보를 논리적 크기에서 픽셀로 변경(Old Architecture에만 적용)
profile
React Native 개발자

0개의 댓글