React Native 0.71:默认使用 TypeScript、Flexbox Gap 等新特性
今天,我们发布了 React Native 0.71 版本!这是一个功能丰富的版本,包括
在这篇文章中,我们将介绍 0.71 的一些亮点。
有关所有更改的完整列表,请查看 CHANGELOG.md。
默认使用 TypeScript
在此版本中,我们正在投资 React Native 的 TypeScript 体验。
从 0.71 开始,当您通过 React Native CLI 创建新的 React Native 应用时,默认会获得一个 TypeScript 应用。新项目已经设置了 tsconfig.json
,因此开箱即用,您的 IDE 将帮助您立即编写类型化代码。
我们还提供直接来自 react-native
包的内置、更准确的 TypeScript 声明。这意味着您不再需要 @types/react-native
,并且类型将与 React Native 版本同步更新。
最后,我们的文档已更新,所有示例均采用 TypeScript。
升级到 React Native 0.71 后,建议从您的 package.json devDependencies
中删除 @types/react-native
。
有关此更改的更多详细信息,包括迁移步骤以及这对 Flow 用户的影响,请查看我们之前的文章 TypeScript 一级支持。
使用 Flexbox gap 简化布局
使用 React Native,您可以使用 Flexbox 在不同的屏幕尺寸上灵活地布局组件。浏览器支持 Flexbox 属性 gap、rowGap 和 columnGap,这些属性允许您指定 Flexbox 中所有项目之间的间距。
这些属性在 React Native 中已被长期要求,0.71 添加了对使用像素值定义的间距的初步支持。在未来的版本中,我们将添加对更多值的支持,例如百分比。
要了解这为什么有用,请想象一下尝试构建一个响应式布局,其中包含大小不同的卡片,每个卡片之间相隔 10 像素,并紧贴父容器的边缘。尝试使用子级边距来实现此布局可能很棘手。
以下显示了一个布局,我们首先为每个子级提供 margin: 10
样式
边距统一应用于所有子级的边缘,并且在 Flexbox 下不会折叠,这使我们在卡片的外部留出了间距,并且与我们期望的相比,内部间距是其两倍。我们可以通过应用非统一边距、在父级上使用负边距、将我们预期的间距减半等方式来解决这个问题,但这可以变得容易得多。
使用 flex gap,可以通过在容器上设置 gap: 10
来实现此布局,以便在卡片内部之间留出 10 像素的间距
有关 Flexbox 间距的更多信息,请参阅 CSS Tricks 的这篇博文。
Web 风格的辅助功能、样式和事件属性
此版本包含许多受 Web 标准启发的新属性,以使 React Native 的 API 在许多平台上保持一致。这些新属性纯粹是新增的,因此对于等效的辅助功能、行为或样式属性,没有预期的迁移或行为更改。
对于引入的任何新的属性别名,如果存在具有不同名称的现有属性并且两者都已指定,则新的别名属性值将优先。例如,此版本为 Image 组件上的 source
添加了一个 src
属性别名,以与 Web 上的 src
属性保持一致。如果同时提供了 src
和 source
,则将使用新的 src
属性。
辅助功能
我们引入了 ARIA 属性作为现有 React Native 辅助功能属性的别名。
这些属性现在存在于 React Native 的所有核心组件上:aria-label
、aria-labelledby
、aria-modal
、id
、aria-busy
、aria-checked
、aria-disabled
、aria-expanded
、aria-selected
、aria-valuemax
、aria-valuemin
、aria-valuenow
和 aria-valuetext
。
我们还引入了等效的 Web 行为:aria-hidden
、aria-live
、role
和 tabIndex
。
有关更多详细信息,请参阅此 问题。
组件特定行为
还引入了属性以使属性名称与核心组件的等效 DOM 属性名称保持一致。
- Image:
alt
、tintColor
、crossOrigin
、height
、referrerPolicy
、src
、srcSet
和width
。 - TextInput:
autoComplete
、enterKeyHint
、inputMode
、readOnly
和rows
。
有关更多详细信息,请参阅此 问题。
样式
为了与某些 CSS 样式保持一致,以下样式已进行了功能扩展。
aspectRatio
现在支持字符串值。fontVariant
现在支持以空格分隔的字符串值。fontWeight
现在支持数字值。transform
现在支持字符串值。
以下别名已添加到现有 React Native 样式中。
更多详细信息,请参阅此 问题。
事件
最后,我们还添加了一个可选的 PointerEvents 实现。
启用后,View
上的以下处理程序将支持悬停。
onPointerOver
、onPointerOut
onPointerEnter
、onPointerLeave
这些事件也已在 Pressability
中实现,以便为悬停提供新的可选支持。
要启用这些功能,请将以下标志设置为 true。
import ReactNativeFeatureFlags from 'react-native/Libraries/ReactNative/ReactNativeFeatureFlags';
// enable the JS-side of the w3c PointerEvent implementation
ReactNativeFeatureFlags.shouldEmitW3CPointerEvents = () => true;
// enable hover events in Pressibility to be backed by the PointerEvent implementation.
// shouldEmitW3CPointerEvents should also be true
ReactNativeFeatureFlags.shouldPressibilityUseW3CPointerEventsForHover =
() => true;
查看我们专门的 PointerEvents 文章 以了解更多信息。
恢复 PropTypes
React Native 的 prop 类型,例如 ViewPropTypes
和 Text.propTypes
,在 0.66 版中已弃用,访问它们将输出弃用警告。当它们在 0.68 版中被移除时,许多开发人员在升级到最新版本的 React Native 时开始遇到错误。
经过一些调查,我们意识到一些问题阻止了社区对弃用警告采取行动。首先,弃用警告并不总是可操作的,这导致人们忽略它们(问题一、问题二)。其次,弃用警告被 错误地过滤了 LogBox.ignoreLogs
。这两个问题现在都已修复,但我们希望给人们更多时间来升级已弃用的调用站点。
因此,在此版本中,我们重新添加了 React Native 的 propTypes,以便人们更容易升级和迁移代码以避免使用它们。deprecated-react-native-prop-types
包也已针对 0.71 版中的所有 props 更新。将来,我们计划继续弃用并再次移除 prop 类型。我们预计,当我们重新考虑移除时,社区将遇到明显更少的问题。
作为此更改的一部分,我们还将从 LogBox.ignoreLog
中移除控制台过滤。这意味着当您升级时,以前使用 Logbox.ignoreLog
过滤的日志将再次出现在控制台中。
这是预期的,因为它允许找到并修复诸如弃用警告之类的日志。
开发人员体验改进
React DevTools
在此版本中,我们将 Web 上两个流行的 React DevTools 功能引入了 React Native。
“点击检查”是 React Dev Tools 左上角的一个选项,它允许您点击应用程序中的项目以在 Dev Tools 中检查它,类似于 Chrome 元素检查器。
组件高亮将突出显示您在 DevTools 中选择的应用程序中的元素,以便您可以查看哪些 React 组件与哪些屏幕元素对应。
以下是这两个功能的实际应用。
Hermes
在 React Native 0.70 中,我们 将 Hermes 设置为 React Native 的默认引擎。
在 React Native 0.71 中,我们对 Hermes 进行了一些显著的改进。
- 改进源映射:通过使用 Metro 通过网络加载源映射,我们恢复了在 Chrome Dev Tools 的最新版本中(在 Flipper 之外)使用源映射的功能。
- 改进
JSON.parse
性能:此版本包含一项性能优化,可将JSON.parse
的性能提高高达 30%。 - 添加对
.at()
的支持:Hermes 现在 支持.at()
用于String
、TypedArray
和Array
。
有关更改的完整列表,请参阅 通往 71 的问题。
新架构
此版本根据我们迄今收集的用户反馈和报告,对实验性的新架构体验进行了许多改进。
- 减少构建时间:新的分发模型使用 Maven Central,这使我们能够大大减少 Android 上的构建时间,解决了 Windows 上的许多构建问题,并提供了与新架构更无缝的体验。在此处了解更多信息。
- 编写更少的 C++ 代码:您现在可以启用新架构,而无需在您的应用程序中添加任何 C++ 代码,并且 CLI 应用程序模板已清除所有 C++ 代码和 CMake 文件。在此处了解更多信息。
- 更好的 iOS 应用程序设置封装:在 iOS 上,我们采用了类似于 Android 的方法,并将设置新架构的大部分逻辑封装在
RCTAppDelegate
类中,这将在将来简化升级,并减少手动中断性更改。 - 更好的 iOS 依赖项管理:对于库维护者,我们添加了一个新的
install_module_dependencies
函数,可以在您的包podspec
中调用,它将安装新架构所需的所有依赖项。 - 错误修复和更好的 IDE 支持:我们修复了用户在我们 新架构工作组 中报告的几个错误和问题(例如 更好的 Android IDE 支持)。
提醒一下,新架构仍然是一个实验性 API 体验,因为我们正在迭代更改以使其更易于采用。请在 新架构文档 中尝试新的简化步骤,并将您遇到的任何反馈发布到 新架构工作组。
其他值得注意的修复
- 更好的堆栈帧折叠:我们 更新了 React Native 的内部帧列表,以便 LogBox 更频繁地显示您的代码而不是 React Native 内部帧,帮助您更快地调试问题。
- 构建时间改进:我们将资源迁移到 Maven Central 以用于预制件,以改进当前和新架构中 Hermes 的构建时间(iOS 和 Android)。
- Android 模板改进:Android 模板已得到大幅清理,现在完全依赖于 React Native Gradle 插件。您可以在模板中或 网站上的新专用页面 中找到配置说明。
重大更改
- 控制台日志记录的更改:
LogBox.ignoreLog
不再过滤控制台日志。这意味着您将开始在控制台中看到您在 LogBox 中已静默的日志。有关更多详细信息,请参阅 此评论。 - 移除 AsyncStorage 和 MaskedViewIOS:这些组件自版本 0.59 起已弃用,因此是时候完全移除它们了。有关替代方案,请查看 React Native Directory 以获取涵盖这些用例的社区软件包。
- JSCRuntime 迁移到 react-jsc:react-jsi 现已拆分为 react-jsc 和 react-jsi。如果您使用 JSCRuntime,则需要添加 react-jsc 作为依赖项(facebook/react-native@6b129d8)。
鸣谢
此版本能够发布,要感谢 70 多位贡献者提交的 1000 多次提交。
我们尤其要感谢为这些主要的 React Native 项目做出贡献的人员。
- Flexbox Gap 支持:@intergalacticspacehighway 和 @jacobp100。
- 受 Web 启发的 props:@gabrieldonadel @dakshbhardwaj @dhruvtailor7 @ankit-tailor @madhav23bansal。
- 代码生成改进:@AntoineDoubovetzky,@MaeIg,@Marcoo09,@Naturalclar,@Pranav-yadav,@ZihanChen-MSFT,@dakshbhardwaj,@dhruvtailor7,@gabrieldonadel,@harshsiri110,@ken0nek,@kylemacabasco,@matiassalles99,@mdaj06,@mohitcharkha,@tarunrajput,@vinayharwani13,@youedd,@byCedric。
最后,感谢 @cortinico,@kelset,@dmytrorykun,@cipolleschi 和 @titozzz 发布此版本!
立即体验 0.71.0!
对于 React Native CLI 用户,请参阅 升级文档,了解如何更新现有项目,或使用 npx react-native init MyProject
创建新项目。
React Native 版本 0.71 将在 Expo SDK 版本 48 中获得支持。
0.71 现在是 React Native 的最新稳定版本,0.68.x 版本现已不再受支持。有关更多信息,请参阅 React Native 的支持策略。