跳到主要内容

React Native 0.78 - React 19 及更多

·10 分钟阅读
Vojtech Novak
Vojtech Novak
Expo 软件工程师
Shubham Gupta
Shubham Gupta
Dream11 软件工程师
Fabrizio Cucci
Fabrizio Cucci
Meta 软件工程师
Riccardo Cipolleschi
Riccardo Cipolleschi
Meta 软件工程师

今天我们很高兴发布 React Native 0.78!

此版本在 React Native 中发布了 React 19,以及其他相关功能,例如对 Android Vector drawables 的原生支持以及对 iOS 的更好的 Brownfield 集成。

亮点

亮点

React 19

React 19 现在可在 React Native 上使用!

React 19 需要更新您的应用,因为我们从 React 18 引入了一些更改。例如,我们删除了一些 API,例如 propTypes,您需要调整您的应用以使其与新版本的 React 兼容。

请按照我们的分步说明升级您的应用到 React 19。

迁移后,您将能够利用 React 的所有新功能,包括(但不限于)

  • Actions 这些是使用异步转换的函数。异步转换自动为您管理数据提交:它们处理待处理状态、乐观更新、错误处理等。
  • useActionState 一个构建在 Actions 之上的实用 hook。它接受一个函数并返回一个包装的 Action 来调用。当 action 被调用时,它将返回 Action 的最后结果及其 pending 状态。
  • useOptimistic 一个新的 hook,简化了在异步请求进行时乐观地显示更新的最终状态。如果请求出错,React 将自动切换回先前的值。
  • use 这是一个新的 API,允许在渲染期间访问资源。您现在可以使用 use 读取 promise 或上下文,React 将暂停直到它们解析。
  • ref 作为 props 您现在可以像处理任何其他 prop 一样将 ref 作为 prop 传递。函数组件将不再需要 forwardRef,您可以立即迁移您的组件。
  • 以及更多其他功能

有关可用新功能的完整列表,请查看 React 19 发布博客文章

React Compiler

React Compiler 是一个构建时工具,旨在通过自动应用 memoization 来优化 React 应用程序。虽然开发人员可以手动使用 useMemouseCallbackReact.memo 等 API 来防止不必要地重新计算应用程序中未更改的部分,但他们也可能忘记或误用这些优化。React Compiler 通过利用其对 JavaScript 和 React 规则的理解来解决这个问题,以自动 memoize 组件和 hook 中的值或值组。

在此版本中,我们简化了在您的 React Native 应用中启用 React Compiler 的过程。在以前的版本中,您必须安装两个软件包:编译器及其运行时。安装这些软件包后,您必须配置 Babel 插件以通过 Metro 启用 React Compiler。

现在,您只需要安装编译器本身并配置 Babel 插件。要了解如何启用它,您可以按照我们的分步指南进行操作。

要验证编译器是否正在运行,您可以打开 React Native DevTools:您应该在组件检查器中看到 memoized 的组件附加了 Memo ✨ 标签。

如果您想了解有关 React Compiler 的更多信息,这些是有用的资源

朝着更小更快的版本发布迈进

我们正在更新我们的发布流程,以便在 2025 年更频繁地发布稳定的 React Native 版本。

您将更容易更新 React Native 版本,因为我们将减少我们发布的破坏性更改的数量。更快的发布也意味着我们内部发布的所有错误修复程序都会更早地到达您手中,您可以从我们在 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 drawables 的支持

在 React Native 0.78 中,我们正在发布一种在 Android 上加载图标、插图和其他图形元素的新方法,即作为 XML 资源。这意味着您可以使用 vector drawables 来显示任何比例的矢量图像而不会损失质量,或者使用 shape drawables 来绘制更基本的美化效果。所有这些都由您熟悉和喜爱的同一个 Image 组件支持。要立即使用此功能,您可以像导入任何其他 静态资源一样导入 XML 资源,方法是在 source prop 中引用它们。此外,使用 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 的 vector drawables 时意识到了一些显着的性能改进。

利用 vector drawables 等资源类型是显示图像而不会损失质量的完美方法,并且可以减小 APK 文件的大小,因为您不需要为每个屏幕密度包含图像类型。此外,vector drawables 在加载后会从内存中复制,因此如果您多次渲染同一个图标,它们将同时显示。

权衡

重要的是要注意,drawable XML 资源并非完美无缺,并且在使用它们时存在限制

  • 它们必须在您的 Android 应用程序的构建时引用。这些资源与 Android Asset Packaging Tool (AAPT) 一起传递到构建步骤中,以将原始 XML 转换为二进制 XML。Android 不支持加载原始 XML 文件,这是一个已知的限制
  • 它们无法通过 Metro 通过网络加载。如果您更改 XML 资源的目录或名称,您将需要每次都重建您的 Android 应用程序。
  • 它们没有尺寸。默认情况下,它们将以 0x0 大小显示,您需要为它们提供宽度和高度才能显示出来。
  • 它们在运行时并非完全可自定义;您只能控制尺寸或整体色调颜色,但您无法自定义资源内部的单个元素属性,例如笔画宽度、边框半径或颜色。这些类型的自定义需要您的 XML 资源的不同变体。
信息

Android 的 vector drawables 不是 react-native-svg 等库的 1:1 替代品。它们专门为 Android 设计,不适用于 iOS。如果您想在所有平台上拥有相同的 SVG,您将必须继续使用 react-native-svg。Vector drawables 仅仅以牺牲自定义为代价提供了性能优势。

iOS 上的 ReactNativeFactory

在 React Native 0.78 中,我们改进了 React Native 在 iOS 上的集成。

此版本引入了一个名为 RCTReactNativeFactory 的新类,允许您创建 React Native 的实例,而无需 AppDelegate。这应该允许您在 ViewController 中创建一个新版本的 React Native,例如。这极大地简化了与 Brownfield 应用的集成。

想象一下,您想在应用的 View Controller 中显示一个 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 将在您导航到 View Controller 后立即加载。

此代码创建了一个 RCTReactNativeFactory,为其分配了一个委托,并要求它为 React Native 的视图创建一个 rootView

委托定义如下,它覆盖了 sourceURLbundleURL 属性,以告知 React Native 它可以在哪里找到要加载到视图中的 JS bundle。

其他破坏性更改

通用

  • React Native DevTools
    • 删除了 FuseboxClient CDP 域
  • Codegen
    • 分离组件数组类型和命令数组类型

Android

  • 可空性更改:将 RootView 迁移到 Kotlin 导致参数类型从可空更改为不可空。
  • 以下类已从 public 移动到 internal,或已删除,并且无法再访问
    • 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 升级助手查看现有项目的 React Native 版本之间的代码更改,以及升级文档。

要创建一个新项目

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

如果您使用 Expo,Expo SDK 的 canary 版本将支持 React Native 0.78

信息

0.78 现在是 React Native 的最新稳定版本,0.75.x 已变为不受支持。有关更多信息,请参阅 React Native 的支持策略。我们的目标是在不久的将来发布 0.75 的最终寿命终止更新。