오늘 우리는 LogBox가 기본적으로 활성화된 상태로 제공되는 React Native 0.63을 출시한다.
LogBox
React Native 커뮤니티에서 자주 제기되는 피드백은 에러와 경고 메시지를 디버깅하기 어렵다는 점이었다. 이를 해결하기 위해 React Native의 전체 에러, 경고, 로그 시스템을 처음부터 다시 설계했다.

LogBox는 React Native의 redbox, yellowbox, 로깅 경험을 완전히 재설계한 것이다. 0.62 버전에서는 LogBox를 옵트인 방식으로 도입했지만, 이번 릴리스에서는 모든 React Native에서 기본 경험으로 제공한다.
LogBox는 에러와 경고 메시지가 너무 장황하거나 형식이 잘못되었거나, 실행 가능한 조치가 없었던 문제를 해결하기 위해 세 가지 주요 목표에 집중했다:
- 간결성: 로그는 문제를 디버깅하는 데 필요한 최소한의 정보만 제공해야 한다.
- 형식화: 로그는 필요한 정보를 빠르게 찾을 수 있도록 잘 정리된 형식이어야 한다.
- 실행 가능성: 로그는 문제를 해결하고 다음 단계로 넘어갈 수 있도록 실행 가능해야 한다.
이러한 목표를 달성하기 위해 LogBox는 다음과 같은 기능을 포함한다:
- 로그 알림: 경고 알림을 재설계하고 에러를 지원하도록 개선했다. 이제 모든
console.warn
과 console.log
메시지는 앱을 가리지 않고 알림으로 표시된다.
- 코드 프레임: 모든 에러와 경고 메시지에는 앱 내에서 로그의 소스 코드를 보여주는 코드 프레임이 포함된다. 이를 통해 문제의 원인을 빠르게 파악할 수 있다.
- 컴포넌트 스택: 모든 컴포넌트 스택은 이제 에러 메시지에서 분리되어 별도의 섹션에 표시되며, 상위 세 개의 프레임이 보인다. 이를 통해 로그 메시지를 어지럽히지 않고 스택 프레임 정보를 일관된 공간에서 확인할 수 있다.
- 스택 프레임 접기: 기본적으로 앱 코드와 관련 없는 호출 스택 프레임을 접어서 React Native 내부 코드를 뒤지는 대신 앱 내 문제를 빠르게 확인할 수 있다.
- 구문 에러 형식화: 구문 에러의 형식을 개선하고 구문 강조가 적용된 코드 프레임을 추가했다. 이를 통해 에러의 소스를 확인하고 수정한 후 React Native의 방해 없이 코딩을 계속할 수 있다.
이 모든 기능은 에러와 경고 간 일관된 디자인으로 통합되었으며, 모든 로그를 하나의 편리한 UI에서 페이징할 수 있도록 개선되었다.
이번 변경으로 YellowBox 대신 LogBox API를 사용한다:
LogBox.ignoreLogs()
: 이 함수는 YellowBox.ignoreLogs([])
를 대체하며, 주어진 문자열이나 정규식과 일치하는 로그를 무시한다.
LogBox.ignoreAllLogs()
: 이 함수는 console.disableYellowBox
를 대체하며, 에러나 경고 알림을 끌 수 있다. 단, 이는 알림만 비활성화하며, 처리되지 않은 에러는 여전히 전체 화면 LogBox를 열 것이다.
0.63 버전에서는 이러한 사용 중단된 모듈이나 메서드를 사용할 때 경고를 표시한다. 0.64 버전에서 이 API가 제거되기 전에 호출 부분을 업데이트해야 한다.
LogBox와 React Native 디버깅에 대한 자세한 내용은 문서를 참고한다.
Pressable
React Native는 플랫폼의 사용자 기대치를 충족하는 애플리케이션을 만들 수 있도록 설계되었다. 이는 React Native로 개발되었다는 사실을 드러내는 작은 단서를 피하는 것을 포함한다. 이러한 단서의 주요 원인 중 하나는 Touchable 컴포넌트들이다: Button
, TouchableWithoutFeedback
, TouchableHighlight
, TouchableOpacity
, TouchableNativeFeedback
, 그리고 TouchableBounce
. 이 컴포넌트들은 사용자 상호작용에 시각적 피드백을 제공해 애플리케이션을 인터랙티브하게 만든다. 하지만 플랫폼의 상호작용과 일치하지 않는 내장 스타일과 효과를 포함하고 있어, 사용자가 React Native로 작성된 경험을 알아챌 수 있다.
또한 React Native가 성장하고 고품질 애플리케이션에 대한 기준이 높아짐에 따라, 이 컴포넌트들은 그에 맞춰 발전하지 못했다. React Native는 이제 Web, Desktop, TV와 같은 플랫폼을 지원하지만, 추가적인 입력 방식에 대한 지원은 부족했다. React Native는 모든 플랫폼에서 고품질 상호작용 경험을 지원해야 한다.
이러한 문제를 해결하기 위해, 새로운 코어 컴포넌트인 Pressable
을 출시했다. 이 컴포넌트는 다양한 유형의 상호작용을 감지하는 데 사용할 수 있다. API는 상위 컴포넌트에서 수동으로 상태를 유지하지 않고도 상호작용의 현재 상태에 직접 접근할 수 있도록 설계되었다. 또한 플랫폼이 호버, 블러, 포커스 등의 기능을 확장할 수 있도록 설계되었다. 대부분의 사람들이 TouchableOpacity
와 같은 기본 경험에 의존하기보다는 Pressable
을 활용해 컴포넌트를 구축하고 공유할 것으로 기대한다.
import {Pressable, Text} from 'react-native';
<Pressable
onPress={() => {
console.log('pressed');
}}
style={({pressed}) => ({
backgroundColor: pressed ? 'lightskyblue' : 'white',
})}>
<Text style={styles.text}>Press Me!</Text>
</Pressable>;
Pressable 컴포넌트의 간단한 예제
더 자세한 내용은 공식 문서에서 확인할 수 있다.
모든 네이티브 플랫폼은 시스템에서 정의한 색상 개념을 가지고 있다. 이 색상들은 라이트 모드나 다크 모드와 같은 시스템 테마 설정, 고대비 모드와 같은 접근성 설정, 그리고 포함된 뷰나 윈도우의 특성과 같은 앱 내부의 컨텍스트에 자동으로 반응한다.
Appearance
API나 AccessibilityInfo
를 통해 이러한 설정 중 일부를 감지하고 스타일을 조정할 수 있지만, 이러한 추상화는 개발 비용이 많이 들 뿐만 아니라 네이티브 색상의 외관을 근사치로만 흉내낸다. 이러한 불일치는 React Native 엘리먼트와 네이티브 엘리먼트가 공존하는 하이브리드 애플리케이션에서 특히 두드러진다.
React Native는 이제 이러한 시스템 색상을 바로 사용할 수 있는 기본 제공 솔루션을 제공한다. PlatformColor()
는 React Native에서 다른 색상과 마찬가지로 사용할 수 있는 새로운 API다.
예를 들어, iOS에서는 시스템이 labelColor
라는 색상을 제공한다. 이 색상을 React Native에서 PlatformColor
를 사용해 다음과 같이 적용할 수 있다:
import {Text, PlatformColor} from 'react-native';
<Text style={{color: PlatformColor('labelColor')}}>
This is a label
</Text>;
Text 컴포넌트의 색상을 iOS에서 정의한 labelColor로 설정한다.
반면 Android는 colorButtonNormal과 같은 색상을 제공한다. 이 색상을 React Native에서 다음과 같이 사용할 수 있다:
import {View, Text, PlatformColor} from 'react-native';
<View
style={{
backgroundColor: PlatformColor('?attr/colorButtonNormal'),
}}>
<Text>This is colored like a button!</Text>
</View>;
View 컴포넌트의 배경색을 Android에서 정의한 colorButtonNormal로 설정한다.
PlatformColor
에 대해 더 자세히 알고 싶다면 공식 문서를 참고하라. 또한 RNTester에 있는 실제 코드 예제도 확인할 수 있다.
DynamicColorIOS
는 iOS 전용 API로, 라이트 모드와 다크 모드에서 사용할 색상을 정의할 수 있다. PlatformColor
와 마찬가지로, 이 API는 색상을 사용할 수 있는 모든 곳에서 사용할 수 있다. DynamicColorIOS
는 내부적으로 iOS의 colorWithDynamicProvider
를 사용한다.
import {Text, DynamicColorIOS} from 'react-native';
const customDynamicTextColor = DynamicColorIOS({
dark: 'lightskyblue',
light: 'midnightblue',
});
<Text style={{color: customDynamicTextColor}}>
This color changes automatically based on the system theme!
</Text>;
시스템 테마에 따라 텍스트 색상을 자동으로 변경한다.
DynamicColorIOS
에 대해 더 자세히 알고 싶다면 공식 문서를 참고하라.
iOS 9 및 Node.js 8 지원 중단
출시된 지 4년이 넘은 iOS 9에 대한 지원을 중단한다. 이 변경으로 특정 iOS 버전에서 기능을 지원하는지 확인하기 위해 네이티브 코드에 추가해야 하는 호환성 검사를 줄일 수 있다. 이는 개발 속도를 높이는 데 도움이 된다. iOS 9의 시장 점유율이 1%에 불과하므로, 고객에게 큰 부정적인 영향을 미치지 않을 것이다.
동시에 Node 8에 대한 지원도 중단한다. Node 8의 LTS 유지보수 주기는 2019년 12월에 종료됐다. 현재 LTS 버전은 Node 10이며, 이제 이 버전을 목표로 한다. React Native 애플리케이션 개발에 여전히 Node 8을 사용하고 있다면, 최신 보안 수정 사항과 업데이트를 받기 위해 업그레이드할 것을 권장한다.
기타 주요 개선 사항
-
<View />
를 <Text />
내에서 명시적 크기 없이 렌더링 지원: 이제 <Text />
컴포넌트 안에 있는 <View />
를 명시적으로 너비와 높이를 설정하지 않고도 렌더링할 수 있다. 이전 React Native 버전에서는 RedBox 오류가 발생했던 문제가 해결되었다.
-
iOS 런치 스크린을 xib
에서 storyboard
로 변경: 2020년 4월 30일부터 App Store에 제출되는 모든 앱은 Xcode 스토리보드를 사용해 앱의 런치 스크린을 제공해야 하며, 모든 iPhone 앱은 모든 iPhone 화면을 지원해야 한다. 이번 커밋은 React Native 기본 템플릿을 이 요구사항에 맞게 조정한다.
감사의 말
0.63 버전을 만드는 데 도움을 준 수백 명의 기여자들에게 감사드립니다!
LogBox
섹션을 작성한 Rick Hanlon과 이 글의 Pressable
부분을 작성한 Eli White에게 특별한 감사를 전합니다.
모든 업데이트를 확인하려면 0.63 변경 로그를 참고하세요.