React Native 0.77 - 新的样式特性、Android 16KB 页面支持、Swift 模板
今天我们很高兴发布 React Native 0.77!
本次发布包含多个特性:新增样式功能,如支持 display: contents、boxSizing、mixBlendMode 以及与 outline 相关的属性,提供更强大的布局选项;Android 16KB 页面的支持以兼容更新的安卓设备。我们还通过迁移社区模板到 Swift 来实现现代化,同时继续支持并维护对偏好 Objective-C 的开发者的兼容性。
亮点
重大变更
亮点
更佳布局、尺寸和混合的新 CSS 特性
React Native 0.77 进一步推进了将 React Native 与 Web 对齐的目标。我们添加了对新的 CSS 属性的支持,让你对应用的布局、尺寸和混合效果拥有更多控制。这些改动可帮助简化复杂布局,增加层次感,同时提升应用的可访问性。
所有这些新特性仅适用于新架构。
使用 display: contents 简化布局
display: contents 属性允许一个元素在布局结构中“消失”,但其子元素仍像直接子元素一样渲染。它对样式处理非常有用,比如你想对子元素应用样式却不影响布局,或构建必须处理事件的包装组件,或者需要与 ShadowTree 交互时。
技术上讲,display: contents 会渲染元素但不生成布局盒子,同时保留元素子元素的布局盒子。带有 display: contents 的元素实际上从视图层级中被“扁平化”了。
来看一个示例,我们想在某个 widget 被点击时显示警告。容器视图中有一个红色的 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 之前是唯一的 boxSizing 选项。若更改默认值,将导致破坏性变更和多个布局突然失常。我们决议保留 border-box 作为默认值以确保向后兼容。
下面示例展示 border-box 与 content-box 之间的区别,两者都设置了 padding: 20 和 borderWidth: 10。使用 border-box 时,尺寸包含边框和内边距;使用 content-box 时,仅由内容决定尺寸。

CSS 混合模式(mixBlendMode)
mixBlendMode 属性允许你控制元素的颜色如何与其堆叠上下文(stacking context)中的其它元素混合。详细混合函数请参考MDN 文档。
为了更精确控制混合范围,我们还支持 isolation 属性。设置 isolation: isolate 将强制该元素形成一个堆叠上下文。这样,你就可以在某些祖先 View 上设置,不让带有 mixBlendMode 的子孙 View 融合超出这个“隔离”视图范围。
mixBlendMode 的取值
normal:元素直接绘制于背景顶部,不混合。multiply:源颜色与目标颜色相乘,替换目标颜色。screen:目标和源色的补色相乘,再取补色。overlay:视背景色不同乘或屏幕混合。darken:选取背景色与源色中较暗的颜色。lighten:选取背景色与源色中较亮的颜色。color-dodge:根据源色调整背景色亮度,黑色画笔无效。color-burn:根据源色调整背景色暗度,白色画笔无效。hard-light:根据源色值乘或屏幕混合,类似强光效果。soft-light:根据源色值调暗或调亮,类似柔光效果。difference:用较亮颜色减去较暗颜色。exclusion:类似 difference,但对比度较低。hue:以源色的色相合成颜色,保持背景的饱和度和亮度。saturation:以源色的饱和度合成颜色,保持背景的色相和亮度。color:以源色的色相和饱和度合成颜色,保持背景的亮度(适合彩色单色图像着色)。luminosity:以源色的亮度合成颜色,保持背景的色相和饱和度(与 Color 模式相反效果)。

Outline 属性
我们新增了 outlineWidth,outlineStyle,outlineSpread 和 outlineColor。这些轮廓属性与相应的 border 属性类似,但它们绘制于边框盒的外侧,而非内边距盒。通过这些属性,可以突出显示元素边框轮廓,而不改变其布局。
详情请参考MDN 文档。

Android 15 版本支持及 16KB 页面支持
Android 15 强制边缘到边缘显示
在上一个版本我们已部分支持 Android 15。Android 15 的一个显著变化是,当构建目标 SDK 版本为 35 时,强制开启边缘到边缘的显示样式。
如果你还未关注此事,请参考我们之前的建议——忽略此点可能导致应用界面崩溃。
若你的应用使用了 react-native-safe-area-context,该库已经帮你处理好边缘到边缘显示的问题。
Android 16 KB 页面大小支持
Android 15 新增了对 16KB 内存页面大小的支持,可带来性能提升,且以前基于 4KB 页面大小的应用可能会在未来设备上不兼容。目前这对开发者是一个可选开关,允许在指定设备上测试以准备未来默认采用 16KB 页面大小。
自 0.77 版本起,React Native 已做好全面支持 16KB 页面大小,开发者即可测试并发布支持该页面大小的应用。
更多信息请查阅官方 Android 开发者网站。
社区 CLI 与模板更新
社区 CLI:废弃 react-native init
此版本完成了自 React Native 0.75 起开始废弃的 react-native init 命令。
提醒一下,你将不能再使用 react-native init,需选择:
- 使用框架 例如 Expo,自身带有独立的新建项目命令:
npx create-expo-app - 直接调用社区 CLI:
npx @react-native-community/cli init
社区 CLI:从 Metro 移除 iOS/Android 运行的快捷键
本版本中我们从 Metro 移除了 ‘a’ 和 ‘i’ 快捷键,这些快捷键原本用于调用社区 CLI 的 run-android 和 run-ios 命令。此快捷键体验较差且不常用,我们认为由框架负责统一终端输出更为合理。
关于此变更详情,可见专门帖文。
社区模板:iOS 使用 Swift 作为主语言
使用 Expo 的项目不会受到此项更改影响。
此次更改通过将三个文件 (main.m,AppDelegate.h 和 AppDelegate.mm) 替换为一个新的 AppDelegate.swift,大幅精简了社区模板。
这技术上属于破坏性变更:升级助手中你会看到从 Objective-C 切换到 Swift 的提示,如图:

你不必迁移到 Swift:iOS 社区模板的 Objective-C++ 版本仍受支持(需集成 RCTAppDependencyProvider)。新建项目默认使用 Swift 作为 iOS 语言,当然你也可以随时迁回 Objective-C。
限制
如果你的应用含有用 C++ 编写的本地模块,无法用 Swift 注册它们,详见此指南。
此类项目请跳过 AppDelegate 迁移,继续用 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];
// 你可以在下面字典中添加自定义初始属性。
// 它们会传递给 React Native 使用的 ViewController。
self.initialProps = @{};
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
// 剩余的 AppDelegate 代码
重大变更
Metro 移除 console.log() 流式传输
我们希望 React Native 的调试环节可靠且符合现代浏览器工具标准。为此,0.77 版本开始移除此前在 0.76 版本弃用的 Metro 内日志转发功能。
此功能基于与设备上调试目标的自定义通信协议。现在,我们彻底转向 Chrome DevTools 协议(CDP)。
- 请使用 React Native DevTools 的丰富控制台面板查看 JS 日志,支持日志过滤、丰富对象检查、实时表达式等。
- 你也可以通过第三方扩展(如 Expo Tools 和 Radon IDE)将 VS Code 连接为 CDP 调试器。
- 这些集成暂不由 React 团队直接支持,我们正计划在 2025 年推出官方 VS Code 支持。
- Expo CLI 仍提供日志流式传输功能。
详情请参阅 为何 JavaScript 日志离开 Metro?
其他重大变更
通用
- 动画
- 原生循环动画不再在每次循环结束时发送 React 状态更新。
- 布局
- 现在支持考虑
ScrollView中粘性标题的position。 - 绝对定位表现更符合规范。
- 现在支持考虑
- JS 模块
- 移除
ReactFabricInternals模块,不再可访问。
- 移除
- 原生模块
- 现在可通过
NativeModules载入 TurboModules,提升原生模块与 Turbo Native Modules 兼容性。
- 现在可通过
- 包管理
- dev-middleware:框架应以 middleware 主机为相对路径指定
serverBaseUrl。
- dev-middleware:框架应以 middleware 主机为相对路径指定
- API 变更
- 从
AppRegistry中移除useConcurrentRoot类型,因已被忽略。 - 从
NativeMethodsTypeScript 定义中移除refs属性。
- 从
- 用户体验
- 移除开发服务器的 “run on iOS” 和 “run on Android” 快捷键命令。
Android
- Kotlin
- 这是首个基于 Kotlin 2.0.21 构建的 React Native 版本。你可以在语言发行说明了解 Kotlin 2.0 相关改动。
- API 变更
- 可空性
ReadableArray中非原始类型的 getter 现在被正确标记为可选。ReactHost.createSurface()方法改为非空返回。
- 重命名
DevSupportManagerBase.getCurrentContext()改名为DevSupportManagerBase.getCurrentReactContext()。
- 可空性
此外,多个 API 被移除或限制可访问,不能再使用。这些是内部 API,非 React Native 开发者直接使用。完整清单请见下面:
被移除的 Android API 列表:
以下包已内部化,不可访问:
com.facebook.react.views.progressbarcom.facebook.react.views.safeareaviewcom.facebook.react.modules.accessibilityinfocom.facebook.react.modules.appstatecom.facebook.react.modules.clipboardcom.facebook.react.modules.devmodulecom.facebook.react.modules.reactdevtoolssettingscom.facebook.react.views.unimplementedview
以下类已内部化或被移除,无法访问:
BackHandler.removeEventListenerBaseViewManagerInterfaceBindingImplCompositeReactPackageDebugOverlayTagsDefaultDevSupportManagerFactory的create()方法DevToolsReactPerfLoggerFabricComponentsImageStoreManagerInteropModuleRegistryNativeModulePerfLoggerNoopPrinterNotThreadSafeViewHierarchyUpdateDebugListenerOkHttpCallUtilPrinterHolderPrinterReactDebugOverlayTagsReactNativeFlipperReactViewBackgroundManagerReactViewGroup.getBackgroundColor()ReactVirtualTextShadowNodeReactVirtualTextViewManagerSimpleSettableFutureSwipeRefreshLayoutManagerTaskCompletionSourceDefaultReactHost.getDefaultReactHost()的jsBundleLoader参数
iOS
- API 变更
- 移除
RCTConstants.RCTGetMemoryPressureUnloadLevelpartialBatchDidFlushRCTRuntimeExecutorUseNativeViewConfigsInBridgelessMode—— 替换为合适的功能标记UseTurboModuleInteropForAllTurboModules—— 互操作层始终开启
- 改动
- 将所有
CGColorRef替换为UIColor。
- 将所有
- 移除
RCTAppDelegate现在要求通过RCTDependencyProvider加载第三方依赖。- CocoaPods 为所有第三方依赖设置 C++ 版本,避免编译问题。
React 19?
React 19 于 2024 年 12 月 6 日发布。
当时,我们已为 React Native 0.77 开启分支,并发布了三个 RC 版本。
故在 React Native 0.77 版本中引入 React 19 已为时过晚。
React 19 将随 React Native 0.78 一同推出,我们已为此版本开通分支。你可以使用以下命令创建基于 React 19 的新应用:
npx @react-native-community/cli init YourReact19App --version 0.78.0-rc.0
致谢
React Native 0.77 包含 1061+ 个提交,贡献者共计 161 人。感谢大家的辛勤付出!
感谢如下额外作者为本次发布文章贡献文档:
- Jakub Piasecki 贡献
display: contents相关内容 - Nick Gerleman、Joe Vilches 和 Jorge Cabiedes Acosta 发布新的样式特性
- Alan Lee 提供 Android 16KB 页面支持内容
- Riccardo Cipolleschi 和 Oskar Kwaśniewski 支持模板迁移到 Swift
- Nicola Corti 贡献
react-native init废弃周期内容 - Alex Hunt 为移除 Metro 中
console.log功能提供内容
升级至 0.77
请使用 React Native 升级助手 查看现有项目在 React Native 版本间的代码变更,配合官方升级文档使用。
新建项目:
npx @react-native-community/cli@latest init MyProject --version latest
若使用 Expo,React Native 0.77 将在 Expo SDK 52 支持(关于如何在 Expo 项目中升级至 React Native 0.77.0 的详细说明将于近期单独发布 Expo 博客)。
0.77 现为 React Native 最新稳定版本,0.74.x 转为不再支持。详情参见 React Native 支持政策。我们计划在近日发布 0.74 的最终维护更新。
