宣布发布 React Native 0.63 及 LogBox
今天我们发布了 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 组件的简单示例
你可以从文档了解更多。
原生颜色(PlatformColor、DynamicColorIOS)
每个原生平台都有系统定义的颜色概念。这些颜色会根据系统主题设置(如浅色或深色模式)、辅助功能设置(如高对比度模式)、乃至于应用上下文(比如视图或窗口的属性)自动响应变化。
虽然可以通过 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 版本!
特别感谢 Rick Hanlon 撰写了有关 LogBox 的部分,感谢 Eli White 撰写了本文中的 Pressable 相关内容。
查看全部更新,请查看 0.63 版本更新日志。