React Native 0.75 - 支持布局中的百分比值、新架构稳定性、模板与初始化更新等
今天我们很高兴发布 React Native 0.75!
本次发布包含多项功能,如 Yoga 3.1 新增对 % 值的支持、针对新架构的多项稳定性修复,以及推荐用户使用 React Native 框架的引入。
亮点
破坏性变更
- TypeScript 中的 Touchable 不再能在泛型表达式中作为类型使用
- 支持 minSdk 23 和 minIOSVersion 13.4 的最后一个版本
- Android:删除了 JSIModule
- Android:弹出菜单从核心库移除
- iOS:完成 PushNotificationIOS 废弃工作
- 社区 CLI:删除 ram-bundle 和 profile-hermes 命令
亮点
Yoga 3.1 和布局改进
自从我们在 React Native 0.74 中发布 Yoga 3.0 版本以来,我们持续推动了许多改进和新的布局能力以助力您的应用开发。React Native 0.75 搭载了 Yoga 3.1,您可以在 Yoga 官方的发布博客中了解更多新特性。
一个显著且备受期待的功能是对 % 值的支持,适用于多处属性,比如 gaps 和 translation。
这些功能仅适用于新架构。如果您期待使用它们,请考虑迁移到新架构。
gap 中的百分比值支持
在 0.75 版本中,gap、columnGap 和 rowGap 属性(详见此处)现在支持传入带 % 的字符串值。
例如:
function App(): React.JSX.Element {
return (
<SafeAreaView
style={{
marginTop: 20,
alignItems: 'center',
flex: 1,
rowGap: '20%',
}}>
<View
style={{flex: 1, flexDirection: 'row', columnGap: '10%'}}>
<View
style={{
backgroundColor: 'purple',
width: 100,
height: 100,
}}
/>
<View
style={{
backgroundColor: 'blue',
width: 100,
height: 100,
}}
/>
<View
style={{
backgroundColor: 'green',
width: 100,
height: 100,
}}
/>
</View>
<View
style={{flex: 1, flexDirection: 'row', columnGap: '10%'}}>
<View
style={{
backgroundColor: 'lime',
width: 100,
height: 100,
}}
/>
<View
style={{
backgroundColor: 'yellow',
width: 100,
height: 100,
}}
/>
<View
style={{
backgroundColor: 'orange',
width: 100,
height: 100,
}}
/>
</View>
<View
style={{flex: 1, flexDirection: 'row', columnGap: '10%'}}>
<View
style={{
backgroundColor: 'red',
width: 100,
height: 100,
}}
/>
<View
style={{
backgroundColor: 'violet',
width: 100,
height: 100,
}}
/>
<View
style={{
backgroundColor: 'magenta',
width: 100,
height: 100,
}}
/>
</View>
</SafeAreaView>
);
}
渲染效果如下:
| Android | iOS |
|---|---|
![]() | ![]() |
translation 中的百分比值支持
transform 属性也可以接受带 % 的值,用于 translate 变换。
举例来说,下面的组件会将红色方块的 X 坐标移动其宽度的 100%,Y 坐标移动其高度的 100%:
function Translated() {
return (
<SafeAreaView
style={{
marginTop: 20,
flex: 1,
rowGap: '20%',
}}>
<View
style={{
backgroundColor: 'red',
width: 100,
height: 100,
transform: [{translateY: '100%'}, {translateX: '100%'}],
}}
/>
</SafeAreaView>
);
}
渲染效果如下:
| Android | iOS |
|---|---|
![]() | ![]() |
新架构稳定性
自从我们在 React Conf 宣布新架构进入 Beta以来,我们发布了大量 bug 修复及稳定性改进。
我们的目标是使新架构能尽快被视为稳定版本。因此,近几个月我们专注于弥合新旧架构之间的差距。以下是部分已解决的 Bug 和缺失功能示例:
- 修复 Android 上
adjustsFontSizeToFit的问题 (#44075) - 修复 Android 上内联视图中
textAlign无效的问题 (#44146) - 修复 iOS 上文字基线被上移的问题 (#44932)
联合 Expo 团队,我们还致力于在React Native Directory中添加新架构支持的信息,让您一眼就能分辨出库是否已经支持新架构:

我们邀请您参与新架构问卷调查,该调查对我们收集宝贵反馈、规划新架构推广的下一步至关重要。
此外,我们还发布了关于新架构中支持 UIManager的文章,里面概述了 Android 上 UIManager API 以及该 API 如何助力更高级应用和库的迁移。
本次发布还包含一个新的、现已官方推荐访问 jsi::Runtime 的 API。
在 TurboModules 中访问 jsi::Runtime
过去,原生模块没有官方推荐的方式访问 jsi::Runtime,使用者通常采用绕过框架的危险方法。在 0.74 版本中,我们引入了实验性 API 以安全访问 jsi::Runtime,0.75 版本我们很高兴宣布这些 API 已稳定。
访问 jsi::Runtime 的示例
在 iOS 上,可以让您的 Turbo 原生模块遵循 RCTTurboModuleWithJSIBindings 协议。您可以实现 installJSIBindingsWithRuntime,从而线程安全地访问 runtime。
@interface RCTSampleTurboModule () <RCTTurboModuleWithJSIBindings>
@end
#pragma mark - RCTTurboModuleWithJSIBindings
- (void)installJSIBindingsWithRuntime:(jsi::Runtime &)runtime {
runtime.global().setProperty(
runtime,
"myGlobalFunction",
jsi::Function::createFromHostFunction(...));
}
在 Android 上,可以让您的 Turbo 原生模块实现 TurboModuleWithBindings 接口。您可以实现 JNI 方法 getBindingsInstaller,从而以线程安全的方式访问 C++ 端的 runtime。
public class SampleTurboModule extends NativeSampleTurboModuleSpec implements TurboModuleWithJSIBindings {
@Override
public native BindingsInstallerHolder getBindingsInstaller();
}
// C++
jni::local_ref<BindingsInstallerHolder::javaobject> SampleTurboModuleJSIBindings::getBindingsInstaller(jni::alias_ref<jni::object> jobj) {
return BindingsInstallerHolder::newObjectCxxArgs(
[](jsi::Runtime& runtime) {
runtime.global().setProperty(
runtime,
"myGlobalFunction",
jsi::Function::createFromHostFunction(...));
}
);
}
如果您位于 UI 线程且需要访问 runtime,我们引入了新的 CallInvoker API。它有一个方法 invokeAsync,将在 JS 线程安全地执行与 JS runtime 相关的工作。此 API 向前兼容。
iOS 上已提供协议 RCTCallInvokerModule。遵循该协议后,运行时会为模块装饰访问 CallInvoker 的功能。
@interface RCTSampleTurboModule() <RCTCallInvokerModule>
[self.callInvoker invokeAsync:^(jsi::Runtime& runtime) {
// 在 JS 线程执行操作
}];
在 Android 上,CallInvoker 可通过 JNI 的 CallInvokerHolder 包装,从 ReactContext 获取后,您可以调用 invokeAsync。
// Java
public abstract CallInvokerHolder getJSCallInvokerHolder();
// C++
jsCallInvokerHolder->cthis()->getCallInvoker()->invokeAsync([&](jsi::Runtime& rt) {
// 在 JS 线程执行操作
});
使用框架
正如我们在今年早些时候的 React Conf 上分享的,推荐使用框架(如 Expo)来构建 React Native 应用。
您可以阅读此前博客文章《通过框架构建 React Native 应用》了解更多。
我们希望为新用户打造成功的起点。我们认为使用框架能最大化您的生产力,并在构建新应用时带来最佳开发体验。
为反映这一推荐,本版本包括以下变更:
- 我们将
/template文件夹从react-native包中移出,迁移到独立仓库:react-native-community/template。 - 我们计划在 2024 年 12 月 31 日终止
react-native init命令的支持。
如果您已经使用如 Expo 这样的框架,这些变更不会对您造成影响。您可以在 Expo SDK 51 中使用 React Native 0.75(具体操作见Expo 专门发布的教程)。
如果您未使用框架或自行构建框架,以下是这些变更对您的影响。
模板迁移到 react-native-community/template
此前,react-native NPM 包内附带 /template 文件夹,Community CLI 用它来创建新项目。这样导致模板更新缓慢,因为每次模板改动都需发布新的 React Native 版本。
鉴于我们最新的框架使用推荐,内置一个固定风格的模板与我们的愿景不符。
因此,我们将模板迁移至 @react-native-community/template 包。
这让社区更容易维护和发展模板,无需每次变更都依赖 React Native 的发布。另外,这将模板更靠近 Community CLI,让大家更方便地检查和依赖该包。
对于使用 Community CLI 创建新项目的用户而言,此变更完全透明。未来相关模板问题请提交至模板问题仓库。诸如 upgrade-helper 等依赖该模板的工具也已相应更新,继续正常工作。
终止 react-native init
与模板类似,react-native init 命令也进行了调整以符合新推荐。
过去,react-native init 是创建新 React Native 项目的默认命令。但在 2024 年,我们认为该命令无法提供框架带来的同等体验。因此,我们不再推荐使用它,而是建议通过框架如 Expo 创建项目。
您仍可用 Community CLI 与模板通过 react-native init 创建项目,但会看到如下警告:

自 2024 年 12 月 31 日起,init 命令将无法创建项目。届时您需选择:
- 使用如 Expo 的框架,使用其专用命令创建新项目,如
npx create-expo-app - 直接调用 Community CLI,命令为
npx @react-native-community/cli init
请注意,react-native config 及其他命令(除了 init)仍继续可用。
为了顺畅迁移,react-native@0.75.0 依赖仍包含 @react-native-community/cli,但我们计划不久后移除此依赖。
自动链接性能提升
在更新 init 命令期间,我们还重构了自动链接逻辑以提升性能,实现了 Android 和 iOS 的构建加速。
使用 React Native 0.75 且使用 Expo 的用户,自动链接步骤在 Android 上快约 6.5 倍,在 iOS 上快约 1.5 倍。详情见这里。
破坏性变更
尽管下面的破坏性变更看起来较多,但主要影响的是使用 React Native 的高级用户。
我们在此完整列出,方便参考。
TypeScript 中的 Touchable 不再能在泛型表达式中作为类型使用
TouchableOpacity 和 TouchableHighlight 组件已转为函数组件,不能再同时作为“值”与“类型”使用。例如以下代码已无效:
import {TouchableHighlight} from 'react-native';
const ref = useRef<TouchableHighlight>();
// ^^^ TS2749: TouchableHighlight 指的是一个值,不能用作类型。
// 是否意图使用 typeof TouchableHighlight?
应替换为使用内置 React 类型 React.ElementRef,或采用 View 类型:
import {TouchableHighlight} from 'react-native';
const ref1 =
useRef<React.ElementRef<typeof TouchableHighlight>>();
// 或者
const ref2 = useRef<View>();
支持 minSdk 23 和 minIOSVersion 13.4 的最后版本
这并非严格的 0.75 破坏性变更,但需说明:React Native 0.75 是最后一个支持 minSdk 23(Android 6.0)和 minIOSVersion 13.4 的版本。
从 0.76 版本起,minSdk 将升级至 24(Android 7.0),minIOSVersion 将升级至 15.1。
详细信息分别在我们的官方声明中可查看 Android 和 iOS。
Android:删除了 JSIModule
com.facebook.react.bridge.JSIModule (源码) 是我们曾为临时允许原生模块直接访问 Android 上 JSI 引入的 API。
此 API 在 0.74 中已被弃用,我们发现开源社区无意义使用,因此在 0.75 中删除。
建议改用 Turbo Native Modules 替代方案。
Android:弹出菜单移出核心
在 0.74 中,我们将 Android 的 PopUpMenu 移到了单独包中,位于 @react-native 作用域。
在 0.75 中,我们删除了核心仍残留的以下方法:
UIManagerModule.showPopupMenu()UIManagerModule.dismissPopupMenu()
请改为使用 <PopupMenuAndroid /> 组件,位于 @react-native/popup-menu-android 包。
iOS:完成 PushNotificationIOS 废弃工作
在 0.74 版本,我们已废弃了 PushNotificationIOS 模块中的部分 API。
今在 0.75 中,我们删除了这些 API,以取消对通知元数据的旧有表示支持。
被删除的 API 如下:
+ (void)didReceiveLocalNotification:(UILocalNotification *)notification;
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification;
请改用 didReceiveNotification:(UNNotification *)notification。
社区 CLI:删除 ram-bundle 和 profile-hermes 命令
我们宣布社区 CLI 中将删除两个关键命令:ram-bundle 和 profile-hermes。
ram-bundle 命令自 React Native 0.59 引入,用于直接从内存加载 bundle 运行。但该功能现已被默认的 JS 引擎 Hermes 替代,请勿继续使用该命令。
profile-hermes 命令是用于对 JS 代码 CPU 性能进行分析的工具,使用旧版 .cpuprofile 格式,已不被新版 Chrome 支持。作为独立命令的该功能也将退出,我们将重点提升调试工具的质量。CPU 分析现可在 实验性新调试器 的“Profiler”面板访问(注:使用 Hermes 时无法通过 Chrome 访问)。
其他破坏性变更
通用
- Codegen
- 生成的纯 C++ TurboModules 类和结构体名略作修改,移除
Cxx标志 - 不再支持浮点枚举,以避免精度误差
- 当 JS 传入
null给原生不可空参数时抛出错误
- 生成的纯 C++ TurboModules 类和结构体名略作修改,移除
- Lint
- ESLint 配置不再在 lint 时运行 prettier
- C++
ScrollViewShadowNode构造函数需新增bool includeTransform参数- 移除 RuntimeExecutor 的
executeAsynchronously和executeSynchronously_CAN_DEADLOCK JsErrorHandlingFunc改名为OnJsError,见JsErrorHandler.hhandleJsError改名为OnJsError,见handleFatalError.h- 从
ReactPrimitives.h移除未使用的import LongLivedObjectCollection和LongLivedObject的 get 方法现须传入 Runtime 参数- 将
utils/jsi.h重命名为jsi-utils.h
- TextInput
- 移除已废弃的
onTextInput回调
- 移除已废弃的
- Pressability
- 移除方法
onLongPressShouldCancelPress_DEPRECATED、onResponderTerminationRequest_DEPRECATED和onStartShouldSetResponder_DEPRECATED
- 移除方法
Android
- ReactViewBackgroundDrawable
- 弃用,推荐使用
CSSBackgroundDrawable,同时移除部分ReactViewBackgroundDrawable和ColorUtil的 API
- 弃用,推荐使用
- ReactContext
ReactContext和ReactApplicationContext变为抽象类,推荐使用BridgeReactContext和BridgelessReactContext- 删除
ReactContext.initializeWithInstance(),请改用BridgeReactInstance - 移除
BridgelessReactContext.getJavaScriptContextHolder(),请改用BridgelessCatalystInstance - 移除
ReactContext.getRuntimeExecutor(),请改用BridgelessCatalystInstance
- 布局
- 增加对百分比 flex gap 值支持,部分方法如
setGap、setRowGap、setColumnGap参数类型由 float 改为 dynamic - Android Manifest 需添加支持
supportsRTL
- 增加对百分比 flex gap 值支持,部分方法如
- Runtime
- 移除 ReactHostImpl 中的
ReactJsExceptionHandler - 不使用默认模板时,应用需自行提供核心 turbomodules
- 移除 ReactHostImpl 中的
- DevSupport
- 修改
DevSupportManagerFactory.create(),新增PausedInDebuggerOverlayManager参数
- 修改
- 测量
- 删除
UIManagerModule.measureLayoutRelativeToParent()
- 删除
iOS
- Runtime
- 移除
[RCTHost getSurfacePresenter]和[RCTHost getModuleRegistry] - 移除
EventPriority类,始终使用默认的EventPriority::AsynchronousBatched,若构建失败,请移除所有EventPriority使用
- 移除
- 图片
- 移除未使用的
RCTImageLoadingPerfInstrumentationEnabled
- 移除未使用的
- 错误处理
- 移除通过
RCTBridge访问RCTRedBox
- 移除通过
- CocoaPods
- 将
BUILD_FROM_SOURCE重命名为RCT_BUILD_HERMES_FROM_SOURCE - 将
React-Codegen重命名为ReactCodegen,更好支持use_frameworks和 Swift
- 将
- TextInput
- 移除已废弃的
onTextInput回调
- 移除已废弃的
致谢
React Native 0.75 包含 1491+ 个提交,由 165 位贡献者 完成。感谢大家的辛勤付出!
感谢以下作者协助撰写本次发布文档的功能介绍:
- Nick Gerleman 和 Joe Vilches —— Yoga 3.1 和布局改进
- Arushi Kesarwani —— 新架构中支持 UIManager
- Phillip Pan —— TurboModules 中访问 jsi::Runtime
- Alan Lee 和 Soe Lynn —— 支持 minSdk 23 和 minIOSVersion 13.4 的最后版本
- Kudo Chien —— 自动链接性能提升
- Alex Hunt —— 移除
ram-bundle和profile-hermes命令
升级到 0.75
请使用 React Native Upgrade Helper 查看不同版本间的代码变更,同时参考官方升级文档。
创建新项目使用命令:
npx @react-native-community/cli@latest init MyProject --version latest
如果您使用 Expo,React Native 0.75 已被支持在 Expo SDK 51 中(如何在 Expo 项目中升级请见此专门教程)。
0.75 现为 React Native 最新稳定版本,0.72.x 进入非支持状态。详情请见 React Native 支持政策。我们计划不久后发布 0.72 的最终生命终止更新。









