跳到主要内容

发布 React Native 0.63,包含 LogBox

·8 分钟阅读
Mike Grabowski
Mike Grabowski
Callstack 首席技术官兼联合创始人

今天我们发布 React Native 0.63,它默认启用了 LogBox。

LogBox

我们经常从社区听到反馈,称 React Native 中的错误和警告难以调试。为了解决这些问题,我们审查了 React Native 中的整个错误、警告和日志系统,并从头开始重新设计了它。

Screenshot of LogBox

LogBox 是 React Native 中完全重新设计的红框、黄框和日志体验。在 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 版本中,当使用这些已弃用的模块或方法时,我们将发出警告。请在这些 API 在 0.64 版本中移除之前更新您的调用站点。

有关 LogBox 和调试 React Native 的更多信息,请参阅此处的文档。

Pressable

React Native 的构建旨在使应用程序满足用户对平台的期望。这包括避免“破绽”——那些会暴露出体验是用 React Native 构建的小细节。这些破绽的一个主要来源是 Touchable 组件:`Button`、`TouchableWithoutFeedback`、`TouchableHighlight`、`TouchableOpacity`、`TouchableNativeFeedback` 和 `TouchableBounce`。这些组件通过允许您为用户交互提供视觉反馈,使您的应用程序具有交互性。然而,由于它们包含的内置样式和效果与平台交互不匹配,用户可以分辨出体验何时是用 React Native 编写的。

此外,随着 React Native 的发展和我们对高质量应用程序的要求提高,这些组件并没有随之发展。React Native 现在支持 Web、桌面和电视等平台,但对其他输入模式的支持一直缺乏。React Native 需要在所有平台上支持高质量的交互体验。

为了解决这些问题,我们正在发布一个名为 `Pressable` 的新核心组件。此组件可用于检测各种类型的交互。API 的设计旨在直接访问当前的交互状态,而无需在父组件中手动维护状态。它还旨在使平台能够扩展其功能,包括悬停、模糊、焦点等。我们期望大多数人将构建并共享在底层利用 `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,可以像 React Native 中的任何其他颜色一样使用。

例如,在 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 类似,这可以在任何可以使用颜色的地方使用。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。其 LTS 维护周期已于 2019 年 12 月到期。当前的 LTS 是 Node 10,它现在是我们目标版本。如果您仍然使用 Node 8 进行 React Native 应用程序开发,我们鼓励您升级以获取所有最新的安全修复和更新。

其他显著改进

  • 支持在 <Text /> 中渲染 <View /> 而无需明确大小:您现在可以在任何 <Text /> 组件中渲染任何 <View />,而无需明确设置其宽度和高度,这以前并非总是可能。在之前的 React Native 版本中,这会导致 RedBox 错误。
  • 将 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 更新日志