今天我们发布了 React Native 0.63,默认启用了 LogBox。
LogBox
我们经常收到社区反馈,指出在 React Native 中错误和警告难以调试。为了解决这些问题,我们全面审视了 React Native 中的错误、警告和日志系统,并从零开始重新设计。

LogBox 是 React Native 中完全重新设计的红框(redbox)、黄框(yellowbox)以及日志体验。在 0.62 版本中,我们引入了 LogBox 作为可选功能。在本次发布中,我们将 LogBox 作为 React Native 的默认体验推出。
LogBox 针对错误和警告过于冗长、格式混乱或无法行动的问题,聚焦于三个主要目标:
- 简洁:日志应提供调试问题所需的最少信息。
- 格式化:日志应格式化以便快速找到所需信息。
- 可操作:日志应是可操作的,以便你能修复问题并继续开发。
为实现这些目标,LogBox 包含:
- 日志通知:警告通知经过重新设计,并增加了对错误的支持,所有 console.warn 和 console.log 消息都会作为通知显示,而不会遮盖你的应用。
- 代码片段:每个错误和警告都包含一个代码片段,显示日志的源代码,直接嵌入应用中,帮助快速定位问题源头。
- 组件堆栈:所有组件堆栈信息从错误消息中剥离,放入单独部分,只显示顶部三个调用帧,这为你提供一个统一、一致的堆栈帧信息区,避免日志信息混乱。
- 堆栈帧折叠:默认情况下,我们折叠与应用代码无关的调用堆栈帧,让你更快看到应用内部问题,而不是筛选 React Native 的内部代码。
- 语法错误格式化:改进了语法错误的格式化,新增带语法高亮的代码片段,便于你看到错误源代码、修复问题,继续开发,避免 React Native 阻碍工作。
我们将这些功能整合到了统一且美观的视觉设计中,错误和警告体验保持一致,且支持翻页浏览所有日志,提升使用愉悦感。
本次变更还将逐步废弃 YellowBox,替换为 LogBox API:
LogBox.ignoreLogs():替代了 YellowBox.ignoreLogs([]),用于静默匹配特定字符串或正则表达式的日志。
LogBox.ignoreAllLogs():替代了 console.disableYellowBox,用于关闭错误和警告通知。注意:此方法仅关闭通知,未捕获错误仍会弹出全屏 LogBox。
在 0.63 中,使用这些已废弃模块或方法时会有警告。请在 0.64 版本移除前尽早更新代码。
有关 LogBox 和调试 React Native 的更多信息,请参阅文档 这里。
Pressable
React Native 的设计旨在满足应用程序对平台体验的预期,其中之一是避免“痕迹”——那些能够暴露应用是用 React Native 构建的小细节。其中一大“痕迹”来源是 Touchable 组件:Button、TouchableWithoutFeedback、TouchableHighlight、TouchableOpacity、TouchableNativeFeedback 和 TouchableBounce。这些组件通过允许你为用户交互提供视觉反馈,使应用具备交互性。然而,由于它们内置了与平台交互不匹配的样式和效果,用户能够识别出应用是用 React Native 编写的。
此外,随着 React Native 发展,且对高质量应用的要求提高,这些组件却未能同步演进。React Native 目前支持 Web、桌面和 TV 等多平台,但对于新输入方式的支持不足。React Native 需要在所有平台上支持高质量的交互体验。
为了解决这些问题,我们推出了新的核心组件 Pressable。该组件可检测多种交互类型。其 API 设计允许直接访问当前交互状态,无需父组件手动维护状态。它还设计成可以让各平台扩展其能力,支持悬停(hover)、失焦(blur)、聚焦(focus)等。我们期望大多数开发者会基于 Pressable 构建并共享组件,而不是依赖 TouchableOpacity 等的默认体验。
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() 是一个新 API,可像使用普通颜色一样使用系统颜色。
例如,在 iOS 上,系统提供了名为 labelColor 的颜色,在 React Native 中可用 PlatformColor 使用:
import {Text, PlatformColor} from 'react-native';
<Text style={{color: PlatformColor('labelColor')}}>
This is a label
</Text>;
把文本颜色设置为 iOS 定义的 labelColor。
相反,Android 提供了如 colorButtonNormal 这样的颜色,你可以这样用:
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 类似,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
发布四年多后,我们停止支持 iOS 9。此变更将帮助我们更快推进开发,减少原生代码中针对各 iOS 版本的兼容性检查。鉴于其市场份额仅为 1%,对你的用户影响应该很小。
同时,我们也不再支持 Node 8。Node 8 的 LTS 支持已于 2019 年 12 月结束。当前 LTS 是 Node 10,且我们以此作为目标版本。如果你仍在用 Node 8 开发 React Native 应用,建议升级以获得最新安全补丁和更新。
其他显著改进
- 支持在
<Text /> 中渲染 <View /> 而不需要明确设定尺寸:你现在可以在任意 <Text /> 组件内部渲染 <View />,无需显式设置其宽高。此前版本会导致红屏错误。
- iOS LaunchScreen 从
xib 改为 storyboard:自 2020 年 4 月 30 日起,所有提交至 App Store 的应用必须使用 Xcode storyboard 来提供启动画面,且所有 iPhone 应用都必须支持所有 iPhone 屏幕尺寸。本次提交调整了默认 React Native 模板以符合此要求。
感谢数百位贡献者帮助实现了 0.63 版本!
查看全部更新,请查看 0.63 版本更新日志。