这个版本在 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
读取Promise
或Context
,React 会在它们解析后恢复渲染。 - ref 作为 prop 传递:现在可以像普通 props 一样传递
ref
。函数组件不再需要forwardRef
,你可以立即迁移你的组件。 - 其他新特性
完整的新特性列表,请查看 React 19 发布博客。
React 编译器(React Compiler)
React Compiler 是一个构建时工具,旨在通过自动应用 记忆化(memoization) 来优化 React 应用。尽管开发者可以手动使用 useMemo
、useCallback
和 React.memo
来防止不必要的重新计算,但也可能遗忘或误用这些优化。React Compiler 通过深入理解 JavaScript 和 React 规则,自动对组件和 Hook 内的值或值组进行记忆化优化。
在这个版本中,我们简化了在 React Native 应用中启用 React Compiler 的流程。在之前的版本中,你需要安装两个包(编译器及其运行时),然后配置 Babel 插件以在 Metro 中启用 React Compiler。
现在,你只需要安装编译器本身,并配置 Babel 插件即可。你可以按照我们的 分步指南 启用它。
如何验证编译器是否运行?
你可以打开 React Native DevTools,在组件检查器(Component Inspector)中,所有被记忆化的组件都会带有 Memo ✨
标签。
了解更多
如果你想深入了解 React Compiler,这些资源可能会有所帮助:
- React Compiler 文档
- 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
标志来恢复日志流:
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 资源,例如:
// via require
<Imagesource={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 开始,你只需按照以下步骤操作:
- 安装所有必要的依赖(参见官方指南)。
- 在你的 ViewController 中添加如下代码:
import React
import React_RCTAppDelegatepublic 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 DEBUGreturn RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")#elsereturn 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 的新项目:
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 以获得最新的功能和支持。
📢 建议开发者尽早升级,以保持项目的安全性、稳定性和新功能支持! 🚀