跳至主内容

React Native 0.78 - React 19 及更多新特性

· 1 分钟阅读
Vojtech Novak
Vojtech Novak
Software Engineer @ Expo
Shubham Gupta
Shubham Gupta
Software Engineer @ Dream11
Fabrizio Cucci
Fabrizio Cucci
Software Engineer @ Meta
Riccardo Cipolleschi
Riccardo Cipolleschi
Software Engineer @ Meta
非官方测试版翻译

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

今天我们非常兴奋地发布 React Native 0.78!

本次更新为 React Native 带来了 React 19,以及其他重要特性,包括对 Android 矢量图形的原生支持以及改进的 iOS 混合开发集成。

重点更新

重点详解

React 19

React 19 现已登陆 React Native!

本次更新需要您升级应用,因为 React 19 引入了从 React 18 开始的部分变更。例如我们移除了 propTypes 等 API,您需要调整应用以兼容新版本 React。

请遵循我们的分步升级指南将应用迁移至 React 19。

迁移完成后,您将能够使用 React 的所有新特性,包括但不限于:

  • 操作(Actions): 使用异步过渡的函数。异步过渡自动管理数据提交:处理等待状态、乐观更新、错误处理等。

  • useActionState: 基于操作构建的实用 Hook。接收函数并返回包装后的可调用操作。调用操作时将返回其最新结果及 pending 状态。

  • useOptimistic: 简化异步请求期间乐观显示最终状态的新 Hook。若请求出错,React 会自动回退至先前值。

  • use: 允许在渲染期间访问资源的新 API。现在可通过 use 读取 Promise 或上下文,React 将暂停直至其解析完成。

  • ref 作为 props: 现在可像普通 prop 一样传递 ref。函数组件不再需要 forwardRef,您现在即可迁移组件。

  • 以及其他多项功能

完整新特性列表请参阅 React 19 发布博客

React 编译器

React 编译器是一款构建时工具,旨在通过自动应用记忆化(memoization)优化 React 应用。开发者虽可手动使用 useMemouseCallbackReact.memo 等 API 来避免应用中未变更部分的不必要重计算,但也可能遗忘或误用这些优化。React 编译器通过其对 JavaScript 和 React 规则的理解,自动在组件和 Hook 内部对值或值组进行记忆化。

本次更新简化了在 React Native 应用中启用 React 编译器的流程。先前版本需要安装两个包:编译器及其运行时。安装后还需通过 Metro 配置 Babel 插件来启用。

现在您只需安装编译器本身并配置 Babel 插件。启用方法请参考我们的分步指南

要验证编译器是否运行,可打开 React Native DevTools:在组件检查器中,被记忆化的组件应带有 Memo ✨ 标签。

深入了解 React 编译器的资源:

迈向更小更快的版本迭代

2025 年我们将更新发布流程,以更频繁地交付稳定的 React Native 版本。

由于我们将减少重大变更的数量,版本更新将更加容易。更快的发布也意味着内部修复的 Bug 能更早触达用户,您可更快使用 React Native 开发的最新特性。

我们认为这种新模式将使 React Native 生态中的每位开发者受益——更少的重大变更意味着更稳定的框架基础。

Metro 中的 JavaScript 日志可选支持

我们新增了通过 Metro 开发服务器恢复 JavaScript 日志流的功能选项,该功能在 0.77 版本中已对 Community CLI 用户移除。这是基于用户反馈及对当前替代方案的评估。

通过新标志 --client-logs 启用该功能。也可通过 npm 脚本设置别名方便使用。

npx @react-native-community/cli start --client-logs

Metro 中的日志流功能未来仍将被移除且默认关闭。但我们计划给予开发者更长的迁移适应期。

此更新也将包含在即将发布的 0.77.1 小版本中。

新增 Android XML 图形资源支持

React Native 0.78 引入了在 Android 上加载图标、插画等图形元素的新方式——XML 资源。这意味着您可以使用矢量图形在任何缩放比例下无损显示矢量图像,或使用形状图形绘制基础装饰元素。这些功能均由您熟悉的 Image 组件支持。要使用此功能,可像引用其他静态资源一样,在 source 属性中引用 XML 资源。使用 XML 资源而非位图还能减小应用体积,并在不同 DPI 屏幕上获得更佳渲染效果。

// via require
<Image
source={require('./img/my_icon.xml')}
style={{width: 40, height: 40}}
/>;

// or via import
import MyIcon from './img/my_icon.xml';
<Image source={MyIcon} style={{width: 40, height: 40}} />;

性能与质量

与其他图片类型类似,Android 的 XML 资源会在非主线程加载和渲染,确保不会丢失任何帧。这意味着资源无法保证即时显示,但在加载过程中也不会阻塞用户输入。当需要同时渲染大量图标时,非线程解码尤为重要。内部应用在使用 Android 矢量可绘制资源时已观察到显著的性能提升。

使用矢量可绘制资源是实现无损画质显示的理想方式,还能缩减 APK 体积——因为无需为每种屏幕密度提供图片资源。此外,矢量资源在内存中只需加载一次,重复渲染相同图标时所有实例会同步显示。

权衡考量

需注意可绘制 XML 资源并非完美解决方案,存在以下使用限制:

  • 必须在 Android 应用构建时引用。这些资源会通过 Android 资源打包工具 (AAPT) 将原始 XML 转换为二进制 XML。Android 不支持加载原始 XML 文件,这是已知限制

  • 无法通过 Metro 从网络加载。若修改 XML 资源的路径或名称,每次都需要重新构建 Android 应用。

  • 没有固有尺寸。默认会以 0x0 尺寸显示,必须显式指定宽高才能呈现。

  • 运行时无法完全自定义:仅能控制整体尺寸或色调,无法修改资源内部元素的笔画宽度、圆角半径或颜色等属性。此类定制需准备不同变体的 XML 资源。

信息

Android 矢量可绘制资源并非 react-native-svg 等库的直接替代品。它们专为 Android 设计且不适用于 iOS。如需跨平台使用相同 SVG,仍需使用 react-native-svg。矢量可绘制资源仅以牺牲定制性为代价换取性能优势。

iOS 的 ReactNativeFactory

React Native 0.78 优化了 iOS 平台的集成体验。

此版本引入新类 RCTReactNativeFactory,无需 AppDelegate 即可创建 React Native 实例。现在您可以在 ViewController 等场景中创建新实例,大幅简化了与混合开发应用(Brownfield)的集成流程。

假设您需要在应用的视图控制器中显示 React Native 视图。升级至 React Native 0.78 后,按照集成指南完成依赖安装后,只需添加以下代码:


+import React
+import React_RCTAppDelegate

public class ViewController {

+ var reactNativeFactory: RCTReactNativeFactory?
+ var reactNativeDelegate: ReactNativeDelegate?

public func viewdidLoad() {
super.viewDidLoad()
// …
+ reactNativeDelegate = ReactNativeDelegate()
+ reactNativeFactory = RCTReactNativeFactory(delegate: reactNativeDelegate!)
+ view = reactNativeFactory.rootViewFactory.view(withModuleName: "<your module name>")
}

}

+class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {

+ override func sourceURL(for bridge: RCTBridge) -> URL? {
+ self.bundleURL()
+ }
+
+ override func bundleURL() -> URL? {
+ #if DEBUG
+ RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
+ #else
+ Bundle.main.url(forResource: "main", withExtension: "jsbundle")
+ #endif
+ }
+}

当您导航至该视图控制器时,React Native 将立即加载显示。

这段代码创建了 RCTReactNativeFactory 实例,为其分配代理,并请求为 React Native 视图创建 rootView

下方定义的代理重写了 sourceURLbundleURL 属性,用于指定 React Native 加载视图所需的 JS 包位置。

其他破坏性变更

通用变更

  • React Native DevTools

    • 移除 FuseboxClient CDP 域
  • 代码生成器

    • 分离组件数组类型与命令数组类型

Android 相关

  • 空值安全性变更:将 RootView 迁移至 Kotlin 导致参数类型从可空变为非空。

  • 以下类已从公开移至内部或移除,无法再访问:

    • com.facebook.react.bridge.GuardedResultAsyncTask
    • com.facebook.react.uimanager.ComponentNameResolver
    • com.facebook.react.uimanager.FabricViewStateManager
    • com.facebook.react.views.text.frescosupport.FrescoBasedReactTextInlineImageViewManager

iOS 相关

  • 图像加载事件尺寸信息从逻辑尺寸改为像素尺寸(仅影响旧架构)

致谢

React Native 0.78 包含来自 87 位贡献者的 509 次提交。感谢所有辛勤付出!

特别感谢为本版本发布文档撰写功能说明的各位作者:

升级至 0.78

对于现有项目,除了升级文档外,请使用 React Native Upgrade Helper 查看 React Native 各版本间的代码变更。

要创建新项目:

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

Expo 用户请关注:React Native 0.78 将在 Expo SDK 金丝雀版本中支持

信息

0.78 现为最新稳定版,0.75.x 进入非支持状态。详见 React Native 支持策略,0.75 最终生命周期更新将于近期发布。