此版本发布了几个特性:新的样式功能,例如支持 display: contents、boxSizing、mixBlendMode 和 outline 相关属性,以提供更强大的布局选项;Android 16KB 页面支持,以兼容较新的 Android 设备。我们还在通过将其迁移到 Swift 来现代化社区模板,同时继续支持和维护与 Objective-C 的兼容性,以满足喜欢它的开发者的需求。
亮点
新的 CSS 特性,用于更好的布局、尺寸和混合
React Native 0.77 进一步实现了我们使 React Native 与 Web 对齐的目标。我们添加了对新的 CSS 属性的支持,以便您更好地控制应用的布局、尺寸和混合。这些更改可以帮助简化复杂的布局,添加纹理,并使您的应用更易于访问。
display: contents
display: contents 属性允许元素从布局结构中消失,而其子元素仍然像它们是父元素的直接子元素一样呈现。当您想要将样式应用于子元素而不影响布局时,在构建必须处理事件的包装组件时,或者如果您需要与 ShadowTree 交互时,它可能很有用。
从技术上讲,display: contents 呈现元素而不生成布局框,但它保留元素的子元素的布局框。具有 display: contents 的元素有效地从视图层次结构中展平。
让我们看一下这个示例,我们希望在按下小部件时显示警报。我们有一个红色的 Widget 在容器视图内:
function Container() {
return (
<View style={styles.container}>
<Widget />
</View>
);
}
现在,让我们构建一个新的 Alerting 包装组件,目标是在按下它下面的组件时警告用户,使用实验性指针事件。为了清晰起见,此组件的背景设置为蓝色。它可能看起来像下面的组件:
function Alerting({children}) {
return (
<View
style={{backgroundColor: 'blue'}}
onPointerDown={() => alert('Hello World!')}>
{children}
</View>
}
function Container() {
return (
<View style={styles.container}>
<Alerting>
<Widget />
</Alerting>
</View>
);
}
这并没有完全达到我们想要的效果。Alerting 添加了一个新的布局框,具有自己的边界,与子 Widget 分开。根据它包装的元素的样式,这可能会导致显着的视觉和功能变化。在此示例中,蓝色背景响应点击并发出警报,而我们只想让红色“Hello World”框在被点击时发出警报。
如果我们再次尝试,同时在 Alerting 的 View 包装器上设置 display: contents,我们只会在用户在 Widget 的原始边界内按下时看到警报。这是因为 Alerting 不再添加自己的框,但仍然可以观察从 Widget 冒泡的指针事件。
function Alerting({children}) {
return (
<View
style={{display: 'contents'}}
onPointerDown={() => alert('Hello World!')}>
{children}
</View>
);
}
// ... function Container ...
Box sizing
boxSizing 属性定义了元素的各种尺寸属性(width、height、minWidth、minHeight 等)的计算方式。如果 boxSizing 是 border-box,则这些尺寸适用于元素的边框框。如果是 content-box,则它们适用于元素的内容框。默认值为 border-box,这与 Web 上的默认值不同。Web 文档是如果您想了解有关此属性如何工作的更多信息的好来源。
要理解 border-box 和 content-box 之间的区别,请查看以下示例,其中两个 View 都具有 padding: 20 和 borderWidth: 10。当使用 border-box 时,我们考虑边框和内边距的尺寸;当使用 content-box 时,我们仅考虑内容的尺寸。
CSS mixBlendMode
mixBlendMode 属性允许您控制元素如何将其颜色与其堆叠上下文中的其他元素混合。为了帮助更精细地控制混合在一起的内容,我们还添加了 isolation 属性。在 View 上设置 isolation: isolate 将强制它形成一个堆叠上下文。因此,您可以在某些祖先 View 上设置此属性,以确保具有 mixBlendMode 的某些后代 View 不会混合超出隔离的 View。
mixBlendMode的取值如下:
-
normal:元素绘制在其背景之上,而不进行混合。
-
multiply:源颜色与目标颜色相乘,并替换目标。
-
screen:将背景和源颜色值的补色相乘,然后对结果求补色。
-
overlay:根据背景颜色值,将颜色相乘或滤色。
-
darken:选择背景和源颜色中较暗的颜色。
-
lighten:选择背景和源颜色中较浅的颜色。
-
color-dodge:使背景颜色变亮以反映源颜色。用黑色绘画不会产生任何变化。
-
color-burn:使背景颜色变暗以反映源颜色。用白色绘画不会产生任何变化。
-
hard-light:根据源颜色值,将颜色相乘或滤色。效果类似于在背景上照射强烈的聚光灯。
-
soft-light:根据源颜色值,使颜色变暗或变亮。效果类似于在背景上照射漫射聚光灯。
-
difference:从较浅的颜色中减去两种组成颜色中较暗的颜色。
-
exclusion:产生与“差异”模式相似但对比度较低的效果。
-
hue:创建一种颜色,该颜色具有源颜色的色调以及背景颜色的饱和度和亮度。
-
saturation:创建一种颜色,该颜色具有源颜色的饱和度以及背景颜色的色调和亮度。
-
color:创建一种颜色,该颜色具有源颜色的色调和饱和度以及背景颜色的亮度。这保留了背景的灰度级别,对于着色单色图像或为彩色图像着色很有用。
-
luminosity:创建一种颜色,该颜色具有源颜色的亮度以及背景颜色的色调和饱和度。这产生了与“颜色”模式相反的效果。
轮廓属性
我们还引入了 outlineWidth、outlineStyle、outlineSpread 和 outlineColor。这些轮廓属性的工作方式与相应的 border 属性非常相似,但它是在边框框周围而不是在内边距框周围呈现的。这些属性允许通过绘制元素的轮廓来突出显示元素,而不会影响其布局。
查看MDN 文档以获取更多详细信息。
Android 版本 15 支持和 16KB 页面支持
Android 15 上的强制边缘到边缘
我们已经在之前的版本中完成了一些工作来支持 Android 15。Android 15 中最显着的变化之一是当您使用 targetSdk 35 构建应用时,强制进行边缘到边缘显示。
如果您尚未研究此内容,请参阅我们之前的建议,了解应如何处理此问题,因为忽略此问题可能会破坏应用中的 UI。
Android 的 16 KB 页面大小支持
Android 15 引入了对 16KB 内存页面大小的支持,从而为应用实现了性能改进等,但使以前基于 4KB 的应用在未来的设备上可能不兼容;目前,这是一个供开发者在选定设备上进行测试的可选功能,以便为 16 KB 页面大小成为操作系统默认值做好准备。
在 0.77 版本中,React Native 已准备好完全支持 16 KB 页面大小,开发者将能够使用它来测试和发布适用于 16 KB 设备的应用程序。
请参阅官方 Android 开发者网站,以获取有关 16 KB 支持的更多信息。
社区 CLI 和模板更新
react-native init 弃用
此版本完全完成了 React Native 0.75 中引入的 react-native init 命令的弃用。
作为提醒,您将无法再使用 react-native init 命令,但您必须执行以下操作之一:
-
使用框架,例如 Expo,及其自己的专用命令来创建新项目:npx create-expo-app
-
使用 npx @react-native-community/cli init 直接调用社区 CLI
从 Metro 中删除“在 iOS/Android 上运行”的按键处理程序
在此版本中,我们从 Metro 中删除了 'a' 和 'i' 键盘快捷键。这些快捷键用于调用 run-android 和 run-ios 社区 CLI 命令。这些键盘快捷键提供了较差的开发者体验,并且很少使用。此外,我们认为框架更适合协调终端输出。
您可以在此专用帖子中阅读有关此更改的更多信息。
Swift 作为 iOS 应用的编程语言
此更改使我们可以通过用一个新的AppDelegate.swift替换三个文件(main.m、AppDelegate.h 和 AppDelegate.mm)来简化社区模板。
从技术上讲,这是一个重大变更:您将在升级助手中看到从 Objective-C 到 Swift 的更改,如下所示:
您不必迁移到 Swift:iOS 社区模板的 Objective-C++ 变体仍然受支持(请注意,您仍然需要集成RCTAppDependencyProvider)。新项目将通过使用 Swift 作为 iOS 应用语言生成,但如果您需要,您可以随时迁移回 Objective-C。
限制
如果您的应用有一些用 C++ 编写的本地模块,您将无法像本指南中所示那样在 Swift 中注册它们。
如果您的应用属于此类别,请跳过 AppDelegate 到 Swift 的迁移,并继续为您的应用使用 Objective-C++。
React Native 核心主要使用 C++ 开发,以鼓励 iOS 和 Android 以及其他平台之间的代码共享。Swift 和 C++ 之间的互操作性尚不成熟且不稳定。我们正在寻找填补这一空白的方法,并让您也迁移到 Swift。
RCTAppDependencyProvider
React Native 0.77 略微更改了应用加载第三方依赖项的方式。这是社区模板中的新行,如果遗漏,可能会导致一些运行时问题。请确保将其添加到您的应用中。
等效的 Objective-C 行如下:
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <ReactAppDependencyProvider/RCTAppDependencyProvider.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.moduleName = @"<Your app Name>";
self.dependencyProvider = [RCTAppDependencyProvider new];
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
// remaining of the AppDelegate
重大变更
移除 Metro 中的 console.log() 流式传输
我们希望 React Native 调试的每个方面都表现可靠,并与现代浏览器工具的功能相匹配。为了达到此质量标准,通过 Metro 进行日志转发(最初在 0.76 中已弃用)在 0.77 中被移除。
此集成依赖于自定义方法与设备上的调试目标进行通信。通过此更改,我们完全转向 Chrome DevTools Protocol (CDP)。
-
要查看 JS 日志,请使用React Native DevTools及其功能齐全的控制台面板 - 支持日志过滤、丰富的对象检查、实时表达式等。
-
您还可以通过第三方扩展(例如Expo Tools 和 Radon IDE)将 VS Code 连接为 CDP 调试器。请注意,这些集成不受 React 团队的直接支持。但是,我们正在努力在 2025 年提供第一方 VS Code 支持。
-
Expo 继续在 Expo CLI 中提供日志流式传输。
其他重大变更
通用
动画
原生循环动画在每次循环结束时都不会发送 React 状态更新。
布局
-
现在将考虑 ScrollView 上粘性标题的 position。
-
绝对定位现在的行为方式更加兼容
JS 模块
移除 ReactFabricInternals 模块,这将不再可访问
原生模块
NativeModules 对象现在可用于在 JS 中加载 turbomodules。这提高了原生模块和 Turbo 原生模块之间的兼容性
包
dev-middleware:框架应指定相对于中间件主机的 serverBaseUrl
API 变更
-
从 AppRegistry 中删除了 useConcurrentRoot 的类型,因为它已被忽略
-
从 NativeMethods TypeScript 定义中删除了 refs 属性。
UX 变更
从开发服务器按键命令中删除“在 iOS 上运行”和“在 Android 上运行”。
Android
Kotlin
- 这是 React Native 的第一个版本,它基于 Kotlin 2.0.21 构建。您可以在语言发布说明中阅读有关 Kotlin 2.0 中即将到来的变更的更多信息。
API 变更
可空性
-
ReadableArray 中的非原始类型 getter 现在已正确地键入为可选
-
使 ReactHost.createSurface() 方法不可为空
已重命名
- DevSupportManagerBase.getCurrentContext() 为 DevSupportManagerBase.getCurrentReactContext()
此外,一些 API 已被删除或限制了可见性,因此它们不再可访问。这些 API 是内部的,React Native 开发者不需要直接访问。您可以在下面找到完整列表,如下。
以下包现在是内部的,不再可访问
com.facebook.react.views.progressbar
com.facebook.react.views.safeareaview
com.facebook.react.modules.accessibilityinfo
com.facebook.react.modules.appstate
com.facebook.react.modules.clipboard
com.facebook.react.modules.devmodule
com.facebook.react.modules.reactdevtoolssettings
com.facebook.react.views.unimplementedview
以下类现在是内部的或已被删除,因此不再可访问
BackHandler.removeEventListener
BaseViewManagerInterface
BindingImpl
CompositeReactPackage
DebugOverlayTags
来自 DefaultDevSupportManagerFactory 的方法 create()
DevToolsReactPerfLogger
FabricComponents
ImageStoreManager
InteropModuleRegistry
NativeModulePerfLogger
NoopPrinter
NotThreadSafeViewHierarchyUpdateDebugListener
OkHttpCallUtil
PrinterHolder
Printer
ReactDebugOverlayTags
ReactNativeFlipper
ReactViewBackgroundManager
ReactViewGroup.getBackgroundColor()
ReactVirtualTextShadowNode
ReactVirtualTextViewManager
SimpleSettableFuture
SwipeRefreshLayoutManager
TaskCompletionSource
来自 DefaultReactHost.getDefaultReactHost() 的参数 jsBundleLoader
iOS
API 变更
已移除
-
RCTConstants.RCTGetMemoryPressureUnloadLevel
-
partialBatchDidFlush
-
RCTRuntimeExecutor
-
UseNativeViewConfigsInBridgelessMode:被适当的功能标志替换
-
UseTurboModuleInteropForAllTurboModules:互操作层始终为 TMs 启用
已更改
- 将 CGColorRef 的用法替换为 UIColor
其他
-
RCTAppDelegate 现在需要使用 RCTDependencyProvider 加载第三方依赖项
-
CocoaPods 为所有第三方依赖项设置 C++ 版本,以避免编译问题。
升级到 0.77
请使用 React Native Upgrade Helper 查看现有项目的 React Native 版本之间的代码更改,以及升级文档。
要创建新项目
npx @react-native-community/cli@latest init MyProject --version latest
如果您使用 Expo,Expo SDK 52 将支持 React Native 0.77(有关如何在您的 Expo 项目中将 React Native 更新到 0.77.0 的说明将在不久的将来在单独的 Expo 博客文章中提供)。