跳至主内容

React Native 0.82 - 一个新时代

· 1 分钟阅读
Vitali Zaidman
Vitali Zaidman
Software Engineer @ Meta
Nicola Corti
Nicola Corti
Software Engineer @ Meta
Gabriel Donadel Dall'Agnol
Gabriel Donadel Dall'Agnol
Software Engineer @ Expo
Alan Hughes
Alan Hughes
Software Engineer @ Expo
非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

今天我们激动地发布 React Native 0.82:这是首个完全运行在新架构上的 React Native 版本。

这是 React Native 的里程碑式版本,我们相信这是一个新时代的开端。未来版本中,我们将移除旧架构中剩余的代码,以减少安装体积并精简代码库。

此外,0.82 版本还提供了名为 Hermes V1 的新版 Hermes 实验性可选支持。我们还将 React 版本更新至 19.1.1 以启用多项 React 功能,并提供了对 DOM Node API 的支持。

重点更新

仅支持新架构

在 React Native 0.76 中,我们宣布新架构已成为 React Native 的默认架构。

经过持续测试和优化,我们有信心将其作为当前及未来 React Native 版本的唯一架构。

这意味着,如果你在 Android 上尝试设置 newArchEnabled=false,或在 iOS 上使用 RCT_NEW_ARCH_ENABLED=0 安装 CocoaPods,这些设置都将被忽略,你的应用仍会使用新架构运行。

如何迁移

如果尚未迁移项目到新架构,建议先将项目升级到 React Native 0.81 或 Expo SDK 54。这些是最后支持旧架构的版本,包含专门帮助迁移的警告和性能优化。
接着在 0.81 中启用新架构并验证应用运行正常。
当你在 0.81 中使用新架构后,即可安全升级到 React Native 0.82,该版本已禁止启用旧架构。

若因不兼容的第三方依赖无法迁移,建议直接联系该库的维护者。

若因 React Native 核心的 bug 受阻,请通过问题追踪器联系我们。

互操作层与第三方库兼容性

在可预见的未来,我们将保留代码库中的互操作层。互操作层所需的所有类和函数都不会很快移除,后续会分享关于移除互操作层的更新。

我们已验证支持双架构的第三方库在 0.82(仅支持新架构)中仍可正常工作。

旧架构类的移除

为确保向后兼容并减少破坏性变更,本版本暂不移除 React Native 核心中的任何旧架构 API。移除旧架构将显著减少整体包体积,因此该工作将从下个 React Native 版本开始。

你可以在 RFC0929: Removal of the Legacy Architecture of React Native 中找到更多信息。

实验性 Hermes V1

React Native 0.82 增加了对启用 Hermes V1 的支持。

Hermes V1 是 Hermes 的下一代版本。我们已经在内部应用中进行了实验,现在也邀请社区一同体验。它在编译器和虚拟机方面都有改进,从而提升了 Hermes 的性能。

在初步测试和基准测试中,Hermes V1 在各种场景下的表现都优于当前版本的 Hermes。我们在 bundle 加载和 TTI(可交互时间)方面都看到了提升。具体提升效果取决于你应用的细节。

在真实世界中的复杂应用 Expensify app 上,我们观察到了如下提升:

MetricAndroid (low end device)iOS
Bundle Load Time3.2% faster9% faster
Total TTI7.6% faster2.5% faster
Content TTI7.2% faster7.5% faster

对于总 TTI(Total TTI),我们测量的是从 bundle 加载到应用的首屏渲染完成并变为可交互状态的时间。

对于内容 TTI(Content TTI),我们测量的是从组件首次渲染到该组件变为可交互状态的时间。

Hermes V1 目前还不包含 JS 到原生代码的编译(之前称为“Static Hermes”)或者 在 React Native EU 2023 上展示的 JIT 编译功能。我们仍在测试这些功能,并将在取得进展后分享更多信息。

如何启用 Hermes V1

信息

在 Hermes V1 的实验阶段,你需要从源代码构建 React Native 才能尝试。一旦 Hermes V1 在未来某个 React Native 版本中成为默认选项,这一限制将被取消。

要在你自己的项目中尝试 Hermes V1,请按照以下步骤操作:

  1. 通过修改 package.json 文件中相应的部分,强制你的包管理器解析 Hermes V1 编译器包的实验版本(注意当前的版本号约定仅适用于 Hermes V1 的实验阶段):
"resolutions": {
"hermes-compiler": "250829098.0.1"
}
  1. android/gradle.properties 文件中添加 hermesV1Enabled=true 来为 Android 启用 Hermes V1:
android/gradle.properties
hermesV1Enabled=true

此外,通过编辑 android/settings.gradle 来配置 React Native 从源代码构建

android/settings.gradle
  includeBuild('../node_modules/react-native') {
dependencySubstitution {
substitute(module("com.facebook.react:react-android")).using(project(":packages:react-native:ReactAndroid"))
substitute(module("com.facebook.react:react-native")).using(project(":packages:react-native:ReactAndroid"))
substitute(project(":packages:react-native:ReactAndroid:hermes-engine")).using(module("com.facebook.hermes:hermes-android:250829098.0.1"))
}
}
  1. 通过设置环境变量 RCT_HERMES_V1_ENABLED=1 来安装 pods,从而为 iOS 启用 Hermes V1。
RCT_HERMES_V1_ENABLED=1 bundle exec pod install

请注意,Hermes V1 与预编译的 React Native 构建不兼容,因此在安装 pods 时请确保不要使用 RCT_USE_PREBUILT_RNCORE 标志。

  1. 要确认你的应用是否运行在 Hermes V1 上,请在应用内或 DevTools 控制台中执行以下代码。这段代码将返回 Hermes 版本,它应该与步骤 1 中指定的版本(250829098.0.1)一致:
// expecting "250829098.0.1" in Hermes V1
HermesInternal.getRuntimeProperties()['OSS Release Version'];

React 19.1.1

此版本的 React Native 搭载了最新的稳定版 React:React 19.1.1

此版本的 React 包含了对 React Native 中 owner stacks 的完整支持。在 React Native 0.80 版本中,当我们发布对 19.1.0 的支持时,我们提到过,如果你使用了 @babel/plugin-transform-function-name Babel 插件,那么 owner stacks 将无法得到完整支持。此版本取消了这一限制,为所有 React Native 用户启用了 owner stacks。

BEFOREAFTER
Example error thrown without Owner Stacks
Example error thrown with Owner Stacks

React 19.1.1 还提升了 React Native 中 Suspense 边界内 useDeferredValuestartTransition 的可靠性。这些是提升应用响应速度的核心 React 功能。此前在 React Native 中与 Suspense 边界配合使用时,两者都会错误地显示后备组件(fallback component)。在 React 19.1.1 中,它们在 React Native 上的表现已与预期一致,行为与 Web 端对齐。

DOM 节点 API

从 React Native 0.82 开始,原生组件将通过 refs 提供类似 DOM 的节点。

此前,原生组件提供的是仅含 measuresetNativeProps 等少量方法的 React Native 特有对象。此版本之后,它们将提供实现 DOM API 子集的节点,用于遍历 UI 树、测量布局等 Web 端常见操作。例如:

function MyComponent(props) {
const ref = useRef();

useEffect(() => {
const element = ref.current;

// New methods
element.parentNode;
element.parentElement;
element.childNodes;
element.children;
const bounds = element.getBoundingClientRect();
const doc = element.ownerDocument;
const maybeElement = doc.getElementById('some-view');

// Legacy methods are still available
element.measure((x, y, width, height, pageX, pageY) => {
/* ... */
});
}, []);

return <View ref={ref} />;
}

此外,这将支持访问由 Text 组件创建的叶子级文本节点,以及代表 React Native 根节点的文档节点

这是向后兼容的变更,新节点将继续实现 measure 等旧版方法。

更多信息请参阅我们的文档

其他变更

Web 性能 API(Canary 版本)

React Native 现已实现 Web 端部分性能 API:

  • 高精度时间:定义 performance.now()performance.timeOrigin

  • 性能时间线:定义 PerformanceObserver 及访问性能条目方法(getEntries(), getEntriesByType(), getEntriesByName()

  • 用户计时:定义 performance.markperformance.measure

  • 事件计时 API:定义向 PerformanceObserver 报告的 event 条目类型

  • 长任务 API:定义向 PerformanceObserver 报告的 longtask 条目类型

这些 API 支持在运行时追踪应用性能指标(用于遥测),未来将在 React Native DevTools 的性能面板中可视化(后续版本提供)。

目前它们仅适用于 canary 发布级别,稳定版将在未来 React Native 版本中发布。

Android 优化调试构建类型

从 React Native 0.82 开始,你可以使用 debugOptimized 构建类型加速开发流程。

Android 默认创建两种构建变体:

  • debug:默认开发用构建,支持连接 React Native DevTools、Metro、Android JVM 和 C++ 调试器等工具

  • release:生产环境构建,经过完全优化和混淆,难以调试

考虑到多数 React Native 开发者无需使用 C++ 调试器,我们引入了 debugOptimized 构建类型。

使用 debugOptimized 时,动画和重渲染速度将显著提升,因为该构建启用了多项 C++ 优化。同时你仍可使用 React Native DevTools 调试 JavaScript 代码。

使用 debugOptimized 时,你将无法使用 C++ 原生调试器,但如果采用 debug 构建类型则仍可正常使用。

要为应用运行 debugOptimized 变体,可执行以下命令:

npx react-native run-android --mode debugOptimized
信息

debugOptimized 构建类型已向后移植至 React Native 0.81 和 Expo SDK 54。

你可以在这些示例中看到 debugOptimized 的实际效果,我们在屏幕上渲染了多个动画:

运行 debug 的构建帧率约为 20FPS,而 debugOptimized 构建则达到约 60FPS:

debugdebugOptimized
Example build running with debugExample build running with debugOptimized

重大变更

未捕获的 Promise 拒绝现在将触发 console.error

继上一版本中改进未捕获 JavaScript 错误的报告机制后,现在未捕获的 Promise 拒绝也将通过该机制上报:

报告到控制台的 Promise 拒绝示例

由于此前存在缺陷,这些错误完全被静默忽略。升级到 React Native 0.81 后,请预期部分既有错误会重新出现。因此,上报至后端的 JavaScript 错误报告可能会出现激增。

其他破坏性变更

通用

  • ReactNativeFeatureFlags 移至 src/private

    • 通常你完全不应依赖 ReactNativeFeatureFlags,因其属于私有 API
  • Appearance.setColorScheme() 类型更新为不再接受空值

    • 需重置配色方案时,请改用 'unspecified' 代替 null/undefined

iOS 平台变更

  • RCTDisplayLink 从旧版 API RCTModuleData 迁移,未来计划移除后者

Android 平台变更

  • 移除意外暴露为 public 的类 com.facebook.react.bridge.JSONArguments

  • 弃用 MessageQueueThreadPerfStats

    • 该 API 已被替换为桩模块,因原统计数据不可靠,请停止依赖此 API
  • Gradle 从 8.x 升级至 9.0.0

C++

  • 移除 CallbackWrapper.h / LongLivedObject.h 的向后兼容头文件
    • 正确引入方式应为 #include <react/bridging/LongLivedObject.h>#include <react/bridging/CallbackWrapper.h>
    • 请勿再使用 #import <ReactCommon/….h> 下的旧引入方式

完整破坏性变更列表请查阅 0.82 版 CHANGELOG

致谢

React Native 0.82 包含来自 93 位贡献者的 868 次提交,感谢大家的辛勤付出!

特别鸣谢在本版本中做出重大贡献的社区成员:

升级到 0.82

对于现有项目,请使用 React Native Upgrade Helper 查看 React Native 版本之间的代码变更,并参考 升级到新版本文档

要创建新项目:

npx @react-native-community/cli@latest init MyProject --version latest

如果你使用 Expo,React Native 0.82 将在 expo@canary 版本中提供。

下一个 SDK 版本,即 SDK 55,将随下一个 React Native 稳定版本 0.83 一起发布。

信息

0.82 现在是 React Native 的最新稳定版本,0.79.x 版本将不再受支持。更多信息请参阅 React Native 的支持政策