这个版本在React Native中集成了React 19,还带来了一些其他相关特性,比如原生支持Android矢量图形(Android Vector drawables),以及在iOS上更好的混合开发(brownfield integration)体验。
亮点
- React 19
- 迈向更小巧、更快速的版本发布
- Metro中JavaScript日志的可选开启功能
- 新增对Android XML图形资源的支持
- iOS上的ReactNativeFactory
React 19
React 19现已在React Native中可用!
React 19的使用需要对应用进行更新,因为与React 18相比,我们引入了一些变化。例如,我们移除了诸如propTypes
这样的API,你需要调整应用,使其与React的新版本兼容。
按照我们的逐步指南,将你的应用升级到React 19。
迁移完成后,你将能够利用React的所有新特性,其中包括(但不限于):
- Actions:这些是使用异步过渡的函数。异步过渡会自动为你管理数据提交:它们处理等待状态、乐观更新、错误处理等。
- useActionState :一个基于Actions构建的实用钩子。它接受一个函数并返回一个包装后的Action以供调用。当调用该Action时,它将返回该Action的最后结果及其
pending
状态。 - useOptimistic:一个新的钩子,可简化在异步请求进行时乐观显示更新最终状态的操作。如果请求出错,React会自动切换回先前的值。
- use :这是一个新的API,允许在渲染期间访问资源。现在你可以使用
use
读取Promise或上下文,React会暂停,直到它们被解析。 - ref作为props :现在你可以像传递其他任何属性一样,将
ref
作为prop
传递。函数组件不再需要forwardRef
,你现在就可以迁移你的组件。
还有许多其他特性。
有关可用新特性的完整列表,请查看React 19的发布博客文章。
React Compiler
React Compiler是一个构建时工具,旨在通过自动应用记忆化(memoization)来优化React应用程序。虽然开发人员可以手动使用诸如useMemo
、useCallback
和React.memo
等API,以防止应用程序中未更改部分的不必要重新计算,但他们也可能会忘记使用这些优化,或者使用不当。React Compiler通过利用其对JavaScript和React规则的理解,自动对组件和钩子中的值或值组进行记忆化,从而解决了这个问题。
在这个版本中,我们简化了在React Native应用中启用React Compiler的过程。在以前的版本中,你必须安装两个包:编译器及其运行时。安装这些包之后,你还必须配置一个Babel插件,通过Metro启用React Compiler。
现在,你只需要安装编译器本身并配置Babel插件即可。要了解如何启用它,你可以按照我们的逐步指南进行操作。
要验证编译器是否正在运行,你可以打开React Native开发工具(React Native DevTools):在组件检查器(Component Inspector)中,你应该会看到被记忆化的组件带有Memo ✨
标签。
如果你想了解更多关于React Compiler的信息,以下是一些有用的资源:
- React Compiler文档
- React Compiler深度解析
迈向更小巧、更快速的版本发布
我们正在更新发布流程,以便在2025年更频繁地发布稳定的React Native版本。
更新React Native版本将变得更加容易,因为我们将减少发布的破坏性更改。更快的版本发布还意味着我们内部修复的所有错误都能更早地推送给你,你也可以从我们在React Native中开发的最新特性中受益。
我们相信这种新模式将使React Native生态系统中的每一位开发者受益,因为更少的破坏性更改意味着有一个更稳定的框架,让大家都能依赖。
Metro中JavaScript日志的可选开启功能
我们添加了一个可选功能,恢复通过Metro开发服务器进行JavaScript日志的流式传输,该功能在0.77版本中对社区命令行界面(Community CLI)用户移除。这是根据用户反馈,以及结合目前替代方案的评估而做出的决定。
要开启该功能,请使用新的--client-logs
标志。为了方便起见,也可以通过npm脚本使用其别名。
bash
npx @react-native-community/cli start --client-logs
Metro中的日志流式传输在未来仍将被弃用,并且默认情况下仍然是关闭的。不过,我们打算给开发者更长的迁移期来适应这一变化。
此更新也将在即将发布的0.77.1小版本中提供。
新增对Android XML图形资源的支持
在React Native 0.78版本中,我们引入了一种在Android上加载图标、插图和其他图形元素的新方式,即作为XML资源加载。这意味着你可以使用矢量图形(vector drawables)在任意缩放比例下显示矢量图像而不失真,或者使用形状图形(shape drawables)绘制更基本的装饰元素。这一切都可以通过你熟悉和喜爱的Image
组件来实现。要使用此功能,你可以像引用其他任何静态资源一样,在source
属性中引用XML资源来导入它们。此外,使用XML资源而不是位图,还可以帮助你减小应用程序的大小,并在不同DPI的屏幕上实现更好的渲染效果。
jsx
// 通过require引入
<Image
source={require('./img/my_icon.xml')}
style={{width: 40, height: 40}}
/>;
// 或者通过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版本中,我们改进了React Native在iOS上的集成。
此版本引入了一个名为RCTReactNativeFactory
的新类,它允许你在无需AppDelegate
的情况下创建React Native实例。例如,这应该能让你在ViewController
中创建一个新的React Native版本。这极大地简化了与混合开发(Brownfield)应用的集成。
假设你想在应用的ViewController
中显示一个React Native视图。从React Native 0.78版本开始,在按照本指南安装所有依赖项之后,你需要做的就是添加以下代码:
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
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
}
}
一旦你导航到该ViewController
,React Native就会在其中加载。
这段代码创建了一个RCTReactNativeFactory
,为其分配了一个委托,并要求它为React Native视图创建一个rootView
。
下面定义了委托,它重写了sourceURL
和bundleURL
属性,以告知React Native可以在何处找到要在视图中加载的JS包。
其他破坏性更改
常规
- React Native开发工具:移除了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次提交。感谢大家的辛勤付出!
感谢所有为本次版本发布文档中的特性进行记录的其他作者:
- Dream11团队对React Native中React 19特性进行的全面测试
- Nicola Corti在加快版本发布方面所做的工作
- Alex Hunt在Metro日志可选开启功能上的工作
- Peter Abbondanzo在Android XML图形资源支持方面的工作
- Oskar Kwaśniewski在ReactNativeFactory上的工作
升级到0.78版本
对于现有项目,请使用React Native升级助手查看不同React Native版本之间的代码变化,同时也可以参考升级文档。
要创建一个新项目:
bash
npx @react-native-community/cli@latest init MyProject --version latest
如果你使用Expo,React Native 0.78将在Expo SDK的金丝雀版本(canary release)中得到支持。
注意事项
0.78版本现已成为React Native的最新稳定版本,0.75.x版本不再受支持。有关更多信息,请参阅React Native的支持政策。我们计划在不久的将来发布0.75版本的最终停用更新。
标签
- 工程
- 亮点
- React 19
- 迈向更小巧、更快速的版本发布
- Metro中JavaScript日志的可选开启功能
- 新增对Android XML图形资源的支持
- iOS上的ReactNativeFactory
- 其他破坏性更改
- 常规
- Android
- iOS
- 鸣谢
- 升级到0.78版本
总结
本文主要介绍了React Native 0.78版本的新特性、改进之处、破坏性变化以及升级指南。新特性包括集成React 19带来的诸多新功能,如Actions、新钩子函数等;简化了React Compiler的启用过程;恢复Metro中JavaScript日志的可选开启功能;新增对Android XML图形资源的支持,能提升性能、减小APK体积,但也存在一些使用限制;iOS上引入RCTReactNativeFactory
类,简化与混合开发应用的集成。同时,该版本有一些破坏性更改,涉及React Native DevTools、代码生成、Android和iOS平台等方面。文章还对参与该版本开发的贡献者表示感谢,并提供了升级到0.78版本的相关方法。