React Native v0.78 更新

这个版本在 React Native 中引入了 React 19 ,并带来了一些重要的新功能,例如 Android 矢量图(Vector Drawables)的原生支持 以及 iOS 更好的 Brownfield 集成

亮点

  • React 19 集成
  • 更小更快的发布节奏
  • 可选择在 Metro 中启用 JavaScript 日志
  • 新增对 Android XML Drawables 的支持
  • iOS 上的 ReactNativeFactory

🚀 这个版本为开发者带来了更好的性能、兼容性和开发体验!

React 19

React 19 现已在 React Native 上可用!

React 19 需要对你的应用进行更新,因为我们对 React 18 进行了一些改动。例如,我们移除了一些 API,如 propTypes,你需要调整你的应用以适配 React 的新版本。

请按照我们的分步指南,将你的应用升级到 React 19。

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

  • Actions :这些是使用异步转换(async transitions)的函数。异步转换会自动管理数据提交,包括处理 pending 状态、乐观更新(optimistic updates)、错误处理等。
  • useActionState :一个基于 Actions 构建的工具钩子。它接受一个函数,并返回一个封装后的 Action。当调用该 Action 时,它将返回 Action 的最新结果及其 pending 状态。
  • useOptimistic:一个新的 Hook,可以在异步请求进行时,简化乐观地展示更新后的最终状态。如果请求出错,React 会自动切换回之前的值。
  • use :一个全新的 API,允许在渲染时访问资源。你现在可以使用 use 读取 PromiseContext,React 会在它们解析后恢复渲染。
  • ref 作为 prop 传递 :现在可以像普通 props 一样传递 ref。函数组件不再需要 forwardRef,你可以立即迁移你的组件。
  • 其他新特性

完整的新特性列表,请查看 React 19 发布博客


React 编译器(React Compiler)

React Compiler 是一个构建时工具,旨在通过自动应用 记忆化(memoization) 来优化 React 应用。尽管开发者可以手动使用 useMemouseCallbackReact.memo 来防止不必要的重新计算,但也可能遗忘或误用这些优化。React Compiler 通过深入理解 JavaScript 和 React 规则,自动对组件和 Hook 内的值或值组进行记忆化优化。

在这个版本中,我们简化了在 React Native 应用中启用 React Compiler 的流程。在之前的版本中,你需要安装两个包(编译器及其运行时),然后配置 Babel 插件以在 Metro 中启用 React Compiler。

现在,你只需要安装编译器本身,并配置 Babel 插件即可。你可以按照我们的 分步指南 启用它。

如何验证编译器是否运行?

你可以打开 React Native DevTools ,在组件检查器(Component Inspector)中,所有被记忆化的组件都会带有 Memo ✨ 标签。

了解更多

如果你想深入了解 React Compiler,这些资源可能会有所帮助:

更小更快的版本发布

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

这将让你更容易更新 React Native 版本,因为我们会 减少重大变更(breaking changes)的数量 。更快的发布周期也意味着,我们的内部 bug 修复将 更早 交付给你,你可以更快地受益于 React Native 最新的功能。

我们相信,这种新的发布模式将使整个 React Native 生态系统的开发者受益 ,因为更少的重大变更意味着更稳定的框架,让大家都能更加放心地依赖它。 🚀

可选启用 Metro 的 JavaScript 日志

我们新增了一个 可选配置 ,可以 恢复 Metro 开发服务器的 JavaScript 日志流 。此前,在 React Native 0.77 版本 中,我们移除了对 Community CLI 用户 的支持。但由于用户反馈较多,并结合我们对替代方案的评估,我们决定在 0.78 版本中提供 可选恢复

如何启用?

你可以使用 --client-logs 标志来恢复日志流:

sh 复制代码
npx @react-native-community/cli start --client-logs

此外,你还可以通过 npm 脚本 来简化命令调用。

未来计划

需要注意的是,Metro 的日志流功能仍计划在未来彻底移除 ,并且默认仍然是关闭的。不过,我们将提供更长的迁移周期,以便开发者适应这一变更。

此外,这一更新也会 回溯到即将发布的 0.77.1 版本,让 0.77 用户也能受益于这项改进。

新增对 Android XML Drawables 的支持

React Native 0.78 版本中,我们引入了一种全新的方式来加载 图标、插图和其他图形元素 ,即 作为 Android XML 资源加载

这意味着你可以使用:

  • 矢量(Vector)Drawable 来显示任意缩放的矢量图,而不会丢失质量。
  • 形状(Shape)Drawable 来绘制基本的装饰性元素。

如何使用?

这项功能完全兼容你已经熟悉的 Image 组件 。你可以像引用其他静态资源一样,在 source prop 中引用 XML 资源,例如:

tsx 复制代码
// 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}} />;

为什么使用 XML Drawables?

相比传统的位图(Bitmap),使用 XML 资源具有以下优势

减少应用体积 ,避免存储多个不同分辨率的图像文件。

更好的跨屏幕渲染效果,在不同 DPI 设备上都能清晰呈现。

🚀 这一改进将使你的 React Native 应用在 Android 上更加高效和灵活!

性能与质量

与其他图像类型一样,Android 的 XML 资源会在主线程之外加载和渲染,因此不会导致帧率下降。这意味着资源可能不会立即显示,但它不会阻塞用户输入,从而保持流畅的交互体验。

异步解码(Off-thread decoding) 在同时渲染多个图标时尤为重要。内部测试显示,使用 Android 矢量图(Vector Drawables) 可以显著提高应用的性能。

为什么使用矢量图?

无损质量 ------矢量图可以在任意缩放情况下保持清晰。

更小的 APK 文件 ------无需为不同屏幕密度包含多个位图文件。

内存优化 ------矢量图加载后会被缓存,因此相同的图标会 同时显示,无需重复解码。


使用 XML Drawables 的权衡

虽然 XML 资源 带来了性能优化,但也有一些限制:

1️⃣ 必须在构建时引用

  • 这些资源会在 构建步骤 中使用 Android 资源打包工具(AAPT) 预编译成二进制 XML。
  • Android 不支持直接加载原始 XML 文件,因此无法在运行时动态引用未编译的 XML 资源。

2️⃣ 不能通过 Metro 加载

  • XML 资源 无法通过网络加载
  • 如果更改 目录文件名,则必须重新编译 Android 应用。

3️⃣ 默认没有尺寸

  • 这些资源默认大小为 0×0 ,你 必须手动指定宽高 才能正常显示。

4️⃣ 运行时定制受限

  • 你只能动态控制 尺寸整体颜色(tint color) ,但无法修改内部属性(如描边宽度、圆角、颜色等)。
  • 如果需要不同的样式变体,必须创建多个 XML 资源文件

重要提示:XML Drawables ≠ react-native-svg

Android 矢量图(Vector Drawables) 无法完全替代 react-native-svg

Vector Drawables 仅适用于 Android ,而 react-native-svg 可在 iOS 和 Android 上通用。

🚀 如果你想在所有平台上保持一致的 SVG 体验,仍需使用 react-native-svg

总结:XML Drawables 适用于 Android 平台,能够提升性能并减少 APK 体积,但在可定制性方面存在一定限制。开发者需要根据实际需求选择合适的方案!

ReactNativeFactory 在 iOS 上的改进

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

这次版本引入了一个新类 RCTReactNativeFactory ,它允许你在 没有 AppDelegate 的情况下 创建 React Native 实例。这样,你可以在 ViewController 中创建 React Native 的新版本,极大简化了与 Brownfield 应用的集成。

用例场景:在 ViewController 中嵌入 React Native 视图

假设你希望在 iOS 应用的 ViewController 中展示一个 React Native 视图。从 React Native 0.78 开始,你只需按照以下步骤操作:

  1. 安装所有必要的依赖(参见官方指南)。
  2. 在你的 ViewController 中添加如下代码:
swift 复制代码
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
    return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
    #else
    return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
    #endif
  }
}

代码说明

  • RCTReactNativeFactory: 该类用于在没有 AppDelegate 的情况下创建 React Native 实例。

  • ReactNativeDelegate : 该委托类重写了 sourceURL bundleURL方法,用来告知 React Native 应该从哪里加载 JS bundle。

  • sourceURL: 定义桥接的资源 URL。

  • bundleURL: 指定 JS bundle 的路径。

工作原理

当你导航到 ViewController 时,React Native 会自动加载到该视图中。这种方式允许你将 React Native 集成到现有的 iOS 应用中,尤其是与 Brownfield 应用(已有的 iOS 项目)集成时,能够显著简化流程。

总结:

React Native 0.78 引入的 RCTReactNativeFactory 类,使得在 iOS 的 ViewController 中嵌入 React Native 变得更加简单和灵活,特别适用于与现有应用的集成。

其他重大变更(Breaking Changes)

React Native 0.78 版本中,我们对多个部分进行了调整,包括 通用变更、React Native DevTools、代码生成、Android 和 iOS,其中一些改动可能会影响你的项目。


通用(General)

React Native DevTools

  • 移除了 FuseboxClient CDP 域(可能影响依赖该功能的开发工具)。

代码生成(Codegen)

  • 组件数组类型 (component array types)和 命令数组类型(command array types)已被分离。

Android 变更

可空性(Nullability)调整

  • RootView 迁移至 Kotlin导致某些参数类型从 可空(nullable)变为非空(non-nullable。这意味着,如果你的代码之前依赖某些可空类型,可能需要调整代码逻辑。

以下类已被移除或改为内部(internal)类,无法再被外部访问

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

如果你的项目依赖这些类,你需要寻找替代方案或调整代码。


iOS 变更

图片加载事件的尺寸信息调整

  • Image 加载事件(Image Load Event)尺寸信息逻辑尺寸(logical size)调整为像素尺寸(pixel size)
  • ⚠️ 仅影响旧架构(Old Architecture) ,使用 Fabric 新架构的应用不受影响

总结

  • React Native DevTools 变更 :移除了 FuseboxClient CDP
  • 代码生成(Codegen)调整:组件数组类型与命令数组类型拆分。
  • Android 迁移至 Kotlin:某些 API 类型变更,并移除/隐藏了一些内部类。
  • iOS 旧架构的图片加载事件变更 :单位从 逻辑尺寸 变为 像素尺寸

建议开发者在升级前仔细检查项目依赖,确保不受这些 breaking changes 影响! 🚀

升级到 React Native 0.78 🚀

如何升级现有项目?

请使用 React Native Upgrade Helper 来查看 不同版本之间的代码变更 ,并参考官方 升级文档 进行迁移。

如何创建新项目?

你可以使用以下命令创建一个 基于 React Native 0.78 的新项目

sh 复制代码
npx @react-native-community/cli@latest init MyProject --version latest
Expo 支持情况

如果你使用 Expo ,React Native 0.78 将在 Expo SDK 的 Canary 版本 中获得支持。请关注 Expo 的后续更新。


重要信息 ⚠️

  • React Native 0.78 现已成为 最新稳定版本
  • React Native 0.75.x 版本已进入不受支持状态
  • 官方计划发布 0.75 的最终更新 ,请尽快升级到 0.78 以获得最新的功能和支持。

📢 建议开发者尽早升级,以保持项目的安全性、稳定性和新功能支持! 🚀

相关推荐
艾小逗2 小时前
vue3中的effectScope有什么作用,如何使用?如何自动清理
前端·javascript·vue.js
明似水6 小时前
Flutter 弹窗队列管理:支持优先级的线程安全通用弹窗队列系统
javascript·安全·flutter
Simaoya7 小时前
【vue】【element-plus】 el-date-picker使用cell-class-name进行标记,type=year不生效解决方法
前端·javascript·vue.js
Dnn017 小时前
vue3+element-push 实现input框粘贴图片或文本,图片上传。
前端·javascript·vue.js
Nuyoah.7 小时前
《Vue3学习手记5》
前端·javascript·学习
曹牧8 小时前
Java 调用webservice接口输出xml自动转义
java·开发语言·javascript
天天扭码8 小时前
2025年了,npm 与 pnpm我们该如何选择
前端·javascript·npm
烛阴8 小时前
10个JavaScript编程技巧,助你成为高效开发高手!
前端·javascript
s9123601018 小时前
rust REGEX和lazy_static 和struct 混用
java·前端·javascript
vvilkim9 小时前
React 与 Vue 虚拟 DOM 实现原理深度对比:从理论到实践
前端·vue.js·react.js